Mam plik o nazwie, w /tmp/urlFile
której każda linia reprezentuje adres URL. Próbuję odczytać z pliku w następujący sposób:
cat "/tmp/urlFile" | while read url
do
echo $url
done
Jeśli ostatni wiersz nie kończy się znakiem nowego wiersza, wiersz ten nie zostanie odczytany. Zastanawiałem się dlaczego?
Czy można odczytać wszystkie wiersze, niezależnie od tego, czy kończą się nowym wierszem, czy nie?
awk 1 /tmp/urlFile
.. więcawk 1 /tmp/urlFile | while ...
Odpowiedzi:
Zrobiłbyś:
(w rzeczywistości ta pętla dodaje brakującą nową linię do ostatniej (innej niż) linii).
Zobacz też:
źródło
printf
wywołania tutaj mają\n
.Wydaje się to częściowo rozwiązane przez
readarray -t
:Należy jednak pamiętać, że chociaż działa to w przypadku plików o rozsądnych rozmiarach, to rozwiązanie wprowadza potencjalny nowy problem z bardzo dużymi plikami - najpierw odczytuje plik do tablicy, która następnie musi być iterowana. W przypadku bardzo dużych plików może to być czasochłonne i zajmować pamięć, potencjalnie aż do awarii.
źródło
Z definicji plik tekstowy składa się z sekwencji wierszy. Linia kończy się znakiem nowej linii. Zatem plik tekstowy kończy się znakiem nowej linii, chyba że jest pusty.
read
Wbudowane jest przeznaczona tylko do odczytu plików tekstowych. Nie przekazujesz pliku tekstowego, więc nie możesz mieć nadziei, że będzie działał bezproblemowo. Powłoka czyta wszystkie linie - pomija dodatkowe znaki po ostatniej linii.Jeśli masz potencjalnie zniekształcony plik wejściowy, w którym może brakować ostatniego wiersza, możesz dodać do niego nowy wiersz, dla pewności.
Pliki, które powinny być plikami tekstowymi, ale nie mają ostatniej linii nowej linii, są często tworzone przez edytory Windows. Zwykle dzieje się to w połączeniu z zakończeniami linii Windows, które są CR LF, w przeciwieństwie do LF Unixa. Znaki CR są rzadko przydatne w dowolnym miejscu i w żadnym wypadku nie mogą pojawiać się w adresach URL, dlatego należy je usunąć.
W przypadku, gdy plik wejściowy jest poprawnie uformowany i kończy się nową linią,
echo
dodaje dodatkową pustą linię. Ponieważ adresy URL nie mogą być puste, po prostu zignoruj puste wiersze.Zauważ też, że
read
nie odczytuje wierszy w prosty sposób. Ignoruje początkowe i końcowe białe znaki, co w przypadku adresu URL jest prawdopodobnie pożądane. Traktuje odwrotny ukośnik na końcu linii jako znak zmiany znaczenia, powodując połączenie następnej linii z pierwszym minus sekwencją odwrotnego ukośnika-nowa linia, co zdecydowanie nie jest pożądane. Powinieneś więc przekazać tę-r
opcjęread
. To jest bardzo, bardzo rzadkie,read
aby być właściwą rzeczą, a nieread -r
.źródło
Cóż,
read
zwraca wartość falsy jeżeli spełnia EOF przed linią, ale nawet jeśli tak, to nadal przypisuje wartość ją przeczytać. Możemy więc sprawdzić, czy końcowe wywołanieread
zwraca coś innego niż pustą linię, i przetworzyć to jak zwykle. Opuść pętlę dopiero poread
zwróceniu wartości false, a linia będzie pusta:źródło
Innym sposobem byłoby tak:
Polecony stąd .
źródło
To jest bezużyteczne użycie
cat
.Jak na ironię, możesz zastąpić ten
cat
proces czymś naprawdę przydatnym: narzędziem, które systemy POSIX mają do dodania brakującej nowej linii i przekształcenia pliku we właściwy plik tekstowy POSIX.Dalsza lektura
źródło
read
jest określone w tych przypadkach.