IFS=在这个bash循环中做什么:`cat file|而IFS=read-r行;做完成`

  • 本文关键字:IFS file read-r cat bash 循环 bash ifs
  • 更新时间 :
  • 英文 :


我正在学习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=

在这个版本中,行内部的空白仍然保留。但是,前面和后面的空白已经被删除。

-rread -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 linet two n line threet ends here'
line one 
 line    two 
 line three      ends here
$ echo $'line one n linet two n line threet ends here' | while IFS= read -r -d$'t' line; do echo "=$line=" ; done
=line one 
 line=
= two 
 line three=

这里,$'...'构造用于输入特殊字符,如换行符n和制表符t。注意,对于-d$'t'read根据制表符将其输入划分为"行"。忽略最后一个选项卡之后的任何内容。

如何处理最困难的文件名

上述功能的最重要用途是处理困难的文件名。由于不能出现在路径/文件名中的一个字符是null字符,因此null字符可以用于分隔文件名列表。例如:

while IFS= read -r -d $'' file
do
    # do something to each file
done < <(find ~/music -type f -print0)

最新更新