Bash, чтение строки за строкой из файла, с IFS
У меня есть этот код из http://bash.cyberciti.biz/guide/While_loop, который используется для чтения строки за строкой из файла
file=/etc/resolv.conf
while IFS= read -r line
do
# echo line is stored in $line
echo $line
done < "$file"
Часть, которую я не понимаю, IFS=
и как она вносит вклад в эту функциональность. Может ли кто-нибудь объяснить это мне? Спасибо.
Ответы
Ответ 1
IFS - это переменная для разделителя строк (или фактически "Внутренний разделитель полей" ). Этот код эффективно удалит разделитель строк для вашей команды чтения и установит ее по умолчанию. Иногда IFS изменяется где-то еще в коде из-за того, что пользователям нужны другие окончания строки, например, чтение одного предложения за раз (IFS=.
) или подобное.
Я предполагаю, что они включали IFS=
здесь только для того, чтобы убедиться, что это работает или все, независимо от предыдущего значения в переменной IFS. Код должен работать без IFS=
Ответ 2
В этом случае IFS
устанавливается в пустую строку, чтобы предотвратить read
удаление дескриптора пробела в строке.
Изменение IFS
обычно выполняется для управления тем, как ввод будет разделен на несколько полей. Но в этом случае, поскольку только одно имя переменной, присвоенное read
, read
, никогда не будет разбивать входные данные на несколько полей независимо от значения IFS
. Однако он удалит ведущее и завершающее пробелы, как указано в спецификации POSIX (если значение IFS
содержит пробелы или не задано).
См. спецификацию POSIX для read и разделение поля для получения подробной информации о том, как это работает.
Ответ 3
В третьем примере на этой странице установка IFS
на null предотвращает разделение слов, что делает этот код неработающим. Вот этот код:
while IFS= read -r field1 field2 field3 ... fieldN
do
command1 on $field1
command2 on $field1 and $field3
..
....
commandN on $field1 ... $fieldN
done < "/path/to dir/file name with space"
Как написано, все слова в строке хранятся в field1
и field2
и т.д., пусты. Измените линию на это, и она будет работать правильно:
while read -r field1 field2 field3 ... fieldN
Ответ 4
Чтобы сделать IFS
подлинный разделитель строк, используйте IFS=$'\012'
.