Я читал, что это плохо писать что-то вроде for line in $(command)
: правильный путь выглядит так:
command | while IFS= read -r line; do echo $line; done
Это прекрасно работает. Но что, если я хочу перебрать содержимое переменной , а не прямой результат команды?
Например, представьте, что вы создали следующий файл quickfox
:
The quick brown
foxjumps\ over -
the
lazy ,
dog.
Я хотел бы иметь возможность сделать что-то вроде этого:
# 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
при использовании, иначеwhile
цикл получит только одну строку ввода. Смотрите, например, разница в выходе междуecho $variable
противecho "$variable"
илиcat <<< $variable
противcat <<< "$variable"
.variable=$(cat quickfox)
вопрос ОП приводит пример того, о чем я говорил. Использование этого$variable
в двойных кавычках включает в себя переводы строк, при использовании его без перевода строки переводятся в пробелы оболочкой. Если вы читаете и обрабатываете построчно, это имеет огромное значение - в первом случае у вас есть несколько строк ввода, а во втором - только одна строка ввода. Входные данные внешне схожи, но на практике совершенно различны в этих двух случаях.cat <<< "$variable" | wc -l
возвращает 5.cat <<< $variable | wc -l
возвращает 1. Если вы хотите / должны сохранить пробел (включая символы новой строки, табуляции, одиночные или множественные пробелы) в переменной, то вы ДОЛЖНЫ заключить двойную кавычку в переменную, когда вы ее используете, в противном случае все они будут превращены в один пробел между каждым «словом».