我正在学习bash,并且看到了以下结构:
cat file | while IFS= read -r line;
do
...
done
谁能解释
IFS=
做什么?我知道它是输入字段分隔符,但是为什么将其设置为空? 最佳答案
IFS
做很多事情,但您正在询问该特定循环。
该循环的作用是保留line
中的前导和尾随空白。为了说明,首先将IFS设置为空:
$ echo " this is a test " | while IFS= read -r line; do echo "=$line=" ; done
= this is a test =
line
变量包含其在stdin上收到的所有空白。现在,考虑使用默认IFS的相同语句:$ echo " this is a test " | while read -r line; do echo "=$line=" ; done
=this is a test=
在此版本中,行内部的空白仍然保留。但是,前导空格和尾随空格已被删除。
-r
在read -r
中做什么?-r
选项可防止read
将反斜杠视为特殊字符。为了说明这一点,我们使用两个echo命令向
while
循环提供两行。观察-r
会发生什么:$ { echo 'this \\ line is \' ; echo 'continued'; } | while IFS= read -r line; do echo "=$line=" ; done
=this \\ line is \=
=continued=
现在,观察没有
-r
会发生什么:$ { echo 'this \\ line is \' ; echo 'continued'; } | while IFS= read line; do echo "=$line=" ; done
=this \ line is continued=
没有
-r
,发生了两次更改。首先,将双反斜杠转换为单反斜杠。第二,第一行末尾的反斜杠被解释为行继续符,并将两行合并为一个。总之,如果您希望输入中的反斜杠具有特殊含义,请不要使用
-r
。如果要将输入中的反斜杠视为纯字符,请使用-r
。多行输入
由于
read
一次只能输入一行,因此IFS行为以影响单行输入的相同方式影响多行输入的每一行。 -r
的行为类似,不同之处在于,如果没有-r
,则可以使用尾随反斜杠将多行合并为一行,如上所示。但是,可以使用read的
-d
标志彻底改变多行输入的行为。 -d
更改read
用于标记输入行结尾的定界符。例如,我们可以使用制表符终止行:$ echo $'line one \n line\t two \n line three\t ends here'
line one
line two
line three ends here
$ echo $'line one \n line\t two \n line three\t ends here' | while IFS= read -r -d$'\t' line; do echo "=$line=" ; done
=line one
line=
= two
line three=
在这里,
$'...'
构造用于输入特殊字符,例如换行符,\n
和制表符\t
。观察到-d$'\t'
,read
根据制表符将其输入划分为“行”。最终选项卡之后的所有内容都将被忽略。如何处理最困难的文件名
上述功能的最重要用途是处理困难的文件名。由于不能在路径/文件名中出现的一个字符是空字符,因此可以使用空字符来分隔文件名列表。举个例子:
while IFS= read -r -d $'\0' file
do
# do something to each file
done < <(find ~/music -type f -print0)
关于bash - IFS =在此bash循环中做什么: `cat file | while IFS= read -r line; do … done`,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26479562/