I odczytać , że jest źle pisać takie rzeczy for line in $(command)
, prawidłowa droga wydaje się być w zamian:
command | while IFS= read -r line; do echo $line; done
To działa świetnie. Ale co, jeśli to, co chcę iterować, to zawartość zmiennej , a nie bezpośredni wynik polecenia?
Na przykład wyobraź sobie, że tworzysz następujący plik quickfox
:
The quick brown
foxjumps\ over -
the
lazy ,
dog.
Chciałbym móc zrobić coś takiego:
# This is just for the example,
# I could of course stream the contents to `read`
variable=$(cat quickfox);
while IFS= read -r line < $variable; do echo $line; done; # this is incorrect
$variable
użyć podwójnego cudzysłowu, gdy go użyjesz, w przeciwnym raziewhile
pętla uzyska tylko jeden wiersz danych wejściowych. Patrz, na przykład, różnica mocy międzyecho $variable
vsecho "$variable"
lubcat <<< $variable
vscat <<< "$variable"
.variable=$(cat quickfox)
pytanie PO stanowi przykład tego, o czym mówiłem. Używanie tego$variable
wewnątrz cudzysłowów obejmuje znaki nowego wiersza, użycie go bez powoduje, że znaki nowego wiersza są tłumaczone na spacje przez powłokę. Jeśli czytasz i przetwarzasz wiersz po wierszu, robi to ogromną różnicę - w tym pierwszym masz wiele linii wejściowych, w drugim masz tylko jedną linię wejściową. Dane wejściowe są powierzchownie podobne, ale w praktyce są całkowicie odmienne w tych dwóch przypadkach.cat <<< "$variable" | wc -l
zwraca 5.cat <<< $variable | wc -l
zwraca 1. Jeśli chcesz / musisz zachować białe znaki (w tym znaki nowej linii, tabulatory, pojedyncze lub wiele spacji) w zmiennej, MUSISZ podwójnie zacytować zmienną, gdy jej używasz, w przeciwnym razie wszystkie zostaną przekształcone w jedną spację między każdym „słowem”.