Próbuję uruchomić for
pętlę dla pliku i chcę wyświetlić całą linię. Zamiast tego wyświetla tylko ostatnie słowo. Chcę pełną linię.
for j in `cat ./file_wget_med`
do
echo $j
done
wynik po uruchomieniu:
Found.
Oto moje dane:
$ cat file_wget_med
2013-09-11 14:27:03 ERROR 404: Not Found.
command-line
bash
scripts
użytkownik192118
źródło
źródło
Odpowiedzi:
for
Pętla dzieli się, gdy widzi spacje, takie jak spacja, tabulator lub znak nowej linii. Dlatego powinieneś użyć IFS (Internal Field Separator) :źródło
unset IFS
później, aby nie wpływać na inne polecenia w tej samej powłoce.$
znaczyIFS=$'\n'
?$
sprawia, że podziały wierszy działają wewnątrz ciągu. Należy to również zrobić zalocal IFS=$'\n'
pomocą funkcji.$'...'
znany „ ANSI-Cfor
pętle domyślnie dzielą się na dowolne białe znaki (spację, tabulator, znak nowej linii); najłatwiejszym sposobem pracy na jednej linii na raz jest użyciewhile read
pętli, która dzieli się na nowe linie:Chciałbym spodziewać Twój komenda wypluć jedno słowo na linię (to co się stało, gdy testowałem go z plikiem własną rękę). Jeśli dzieje się coś innego, nie jestem pewien, co może być przyczyną.
źródło
for i in `ls`; do echo $1; done
, za potokiem wyjście do polecenia while:ls|while read i; do echo $i; done
. Działa to na nazwach plików / folderów ze spacjami, bez potrzeby zmiany zmiennych środowiskowych. Bardzo dobra odpowiedź.ls
nie jest uważany za bezpieczny w użyciu|
(operator potoku).find
jest bardziej elastyczny poza tym, że jest w tym celu bezpieczniejszy.pbpaste | while read t; do echo "<string>$t</string>"; done
ls -1
może być używany w|
celu zagwarantowania niesformatowanego wyjścia jeden na linięSprawdzona praca, nie ta jedna wkładka, której prawdopodobnie chcesz, ale nie jest to możliwe elegancko.
źródło
Oto niewielkie rozszerzenie odpowiedzi Mitchella Currie, które podoba mi się ze względu na niewielki zakres skutków ubocznych, co pozwala uniknąć konieczności ustawiania zmiennej:
źródło
-name '*'
i byłoby tak samo, nie?Chciałbym napisać tak:
ponieważ wymaga najmniejszych zmian w oryginalnym skrypcie (z wyjątkiem rozwiązania używającego
IFS
, ale modyfikujebash
zachowanie nie tylko dla tej instrukcji sterowania pętlą).źródło
cat
są tutaj niepotrzebne.while
pętla akceptuje przekierowanie w porządku, dlatego zwykle jest to napisane jakowhile IFS= read -r line; do...done < input.txt
Mapfile to wygodny sposób odczytu linii z pliku do tablicy indeksowanej, nie tak przenośny jak odczyt, ale nieco szybszy. Używając pętli for, unikniesz tworzenia podpowłoki.
Pamiętaj, że podczas korzystania z potoków umieści pętlę while w podpowłoce. Zmiany w zmiennych podobnych do pętli while nie będą się rozprzestrzeniać na zewnętrzną część skryptu.
Przykład:
(Lepsze rozwiązanie):
źródło
Dandalf zbliżył się do rozwiązania funkcjonalnego, ale NIGDY nie należy próbować przypisywać wyniku nieznanych ilości danych wejściowych (tj.
find ~/.gdfuse -name '*'
) Zmiennym! Lub przynajmniej próbuj zrobić coś takiego za pomocą zmiennej tablicowej; jeśli nalegacie na bycie tak leniwymi! Oto rozwiązanie Dandalfa wykonane bez niebezpiecznego manewru; i ogólnie w jednym wierszuźródło