Bash,从文件中逐行读取,使用 IFS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4385772/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash, read line by line from file, with IFS
提问by wakandan
I'm having this code from http://bash.cyberciti.biz/guide/While_loop, used to read line by line from a file
我有来自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"
the part I don't understand is IFS=
and how it contributes to this functionality. Could anybody explain this to me? Thanks.
我不明白的部分是IFS=
以及它如何有助于此功能。有人可以向我解释一下吗?谢谢。
采纳答案by Emil Vikstr?m
IFS is a variable for the line separator (or actually "Internal Field Separator"). That code will effectively empty out the line separator for your read command and set it to its default. Sometimes IFS is changed somewhere else in the code due to users wanting other "line" endings, like reading one sentence at a time (IFS=.
) or similar.
IFS 是行分隔符(或实际上是“内部字段分隔符”)的变量。该代码将有效地清空读取命令的行分隔符并将其设置为默认值。有时,由于用户想要其他“行”结尾,例如一次阅读一个句子 ( IFS=.
) 或类似内容,IFS 会在代码中的其他地方更改。
I guess they included the IFS=
here just to make sure it works or everyone, regardless of the previous value on the IFS variable. The code should still work without IFS=
我想他们在IFS=
此处包含只是为了确保它或每个人都有效,而不管 IFS 变量的先前值如何。代码应该仍然可以工作IFS=
回答by Richard Hansen
In this case, IFS
is set to the empty string to prevent read
from stripping leading and trailing whitespace from the line.
在这种情况下,IFS
设置为空字符串以防止read
从行中剥离前导和尾随空格。
Changing IFS
is usually done to control how the input will be split into multiple fields. But in this case, because there's only one variable name given to read
, read
won't ever split the input into multiple fields regardless of the value of IFS
. It will, however, remove the leading and trailing whitespace as mandated in the POSIX specification (assuming the value of IFS
contains whitespace or is unset).
更改IFS
通常用于控制如何将输入拆分为多个字段。但在这种情况下,因为只有一个变量名被赋予read
,read
无论 的值如何,都不会将输入拆分为多个字段IFS
。但是,它将按照 POSIX 规范中的规定删除前导和尾随空格(假设 的值IFS
包含空格或未设置)。
See the POSIX specification for readand field splittingfor details about how it works.
回答by Paused until further notice.
In the third example on that page, setting IFS
to null prevents word splitting which makes that code not work. Here is that code:
在该页面的第三个示例中,设置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"
As written, all the words on the line are stored in field1
and field2
, etc., are empty. Change the line to this and it will work properly:
正如所写的那样,该行上的所有单词都存储在field1
and 中field2
,等等,都是空的。将行更改为此,它将正常工作:
while read -r field1 field2 field3 ... fieldN
回答by user3673660
To make IFS
a genuine line separator, use IFS=$'\012'
.
要制作IFS
真正的行分隔符,请使用IFS=$'\012'
.