Ответ 1
Проблема не в cat
, ни в петле for
per se; он использует обратные кавычки. Когда вы пишете:
for i in 'cat file'
или лучше):
for i in $(cat file)
или (в bash
):
for i in $(<file)
оболочка выполняет команду и фиксирует вывод как строку, разделяя слова на символы в $IFS
. Если вы хотите, линии ввода в $i
, вы должны либо возиться с IFS
или использовать while
цикл. В while
петля лучше, если есть какая- либо опасность, что файлы будут обрабатываться большой; он не должен сразу читать весь файл в памяти, в отличие от версий с помощью $(...)
.
IFS='
'
for i in $(<file)
do echo "$i"
done
Котировки вокруг "$i"
как правило, являются хорошей идеей. В этом контексте, с измененным $IFS
, это на самом деле не критично, но хорошие привычки - хорошие привычки. Это имеет значение в следующем сценарии:
old="$IFS"
IFS='
'
for i in $(<file)
do
(
IFS="$old"
echo "$i"
)
done
когда файл данных содержит несколько пробелов между словами:
$ cat file
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$
Вывод:
$ sh bq.sh
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$
Без двойных кавычек:
$ cat bq.sh
old="$IFS"
IFS='
'
for i in $(<file)
do
(
IFS="$old"
echo $i
)
done
$ sh bq.sh
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$