IFS = $'\ n'的确切含义是什么?

如果以下示例将IFS环境variables设置为换行符…

 IFS=$'\n' 
  • 美元符号意味着什么
  • 它在这个特定的情况下做了什么?
  • 我在哪里可以阅读更多关于这个特定的用法(Google不允许在search中使用特殊字符,否则我不知道要寻找什么)?

我知道IFS环境variables是什么, \n字符是什么(换行符),但是为什么不使用下面的forms: IFS="\n" (这不起作用)?

例如,如果我想循环遍历一个文件的每一行,并想要使用for循环,我可以这样做:

 for line in (< /path/to/file); do echo "Line: $line" done 

但是,除非IFS设置为换行符,否则这将无法正常工作。 要做到这一点,我必须这样做:

 OLDIFS=$IFS IFS=$'\n' for line in (< /path/to/file); do echo "Line: $line" done IFS=$OLDIFS 

注:我不需要另一种方法来做同样的事情,我已经知道很多其他的方法了…我只是对这个$'\n'很好奇,并想知道有没有人能给我一个解释。

通常bash不能解释string中的转义序列。 所以,如果你写\n"\n"'\n' ,那不是换行符 – 它是字母n (在第一种情况下)或反斜杠后跟字母n (在另外两种情况下)。

$'somestring'是一个带有转义序列的string文法 。 所以不像'\n'$'\n'实际上是一个换行符。

http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html

“$'STRING'”forms的单词以特殊的方式处理。 该字扩展为一个string,反斜杠转义的字符被ANSI-C标准指定。 反斜杠转义序列可以在Bash documentation.found中find

我想这是迫使脚本逃避行饲料正确的ANSI-C标准。

只要给出构造它的正式名称$'...'forms的string被称为ANSI C引用的string

也就是说,就像[ANSI] Cstring一样, 间隙转义序列被识别并扩展到它们的字面值 (参见下面的支持转义序列的完整列表)。

这个扩展之后, $'...'string的行为与$'...'string的行为相同 – 也就是说,它们被视为不受任何[进一步] shell扩展的文字限制

例如, $'\n'扩展为文字换行符 – 这是一个常规的bashstring文字(不pipe是'...'还是"..." )不能做的事情。 [1]

另一个有趣的特性是ANSI C引用的string可以像\'一样转义' (单引号)'...' (常规的单引号string)不能:

 echo $'Honey, I\'m home' # OK; this cannot be done with '...' 

支持的转义序列列表

反斜杠转义序列(如果存在)按如下方式解码:

警钟(钟)

\ b退格

\ e \ E转义符(不是ANSI C)

\ f换页

\ n换行符

\ r回车

\ t水平标签

\ v垂直标签

\反斜杠

“单引号

“双引号

\ n在8位字符的值是八进制值nnn(一到三位数字)

\ xHH值是hex值HH的八位字符(一个或两个hex数字)

Unicode(ISO / IEC 10646)字符,其值是hex值HHHH(1到4个hex数字)

\ UHHHHHHHH Unicode值(ISO / IEC 10646)字符,其值是hex值HHHHHHHH(1到8个hex数字)

\ cx一个控制x字符

扩大的结果是单引号的,好像美元符号不存在。


[1]但是,您可以在“…”和“…”string中embedded实际换行符; 即,您可以定义跨越多行的string。

重新恢复默认的IFS-这个OLDIFS=$IFS是没有必要的。 在子shell中运行新的IFS以避免覆盖默认的IFS:

 ar=(123 321); ( IFS=$'\n'; echo ${ar[*]} ) 

另外我真的不相信你完全恢复了旧的IFS。 您应该双引号以避免断行,如OLDIFS="$IFS"

ANSI C引用的string是一个关键点。 感谢@ mklement0。

您可以使用od命令testingANSI C引用的string。

 echo -n $'\n' | od -c echo -n '\n' | od -c echo -n $"\n" | od -c echo -n "\n" | od -c 

输出:

 0000000 \n 0000001 0000000 \ n 0000002 0000000 \ n 0000002 0000000 \ n 0000002 

你可以清楚地知道输出的含义。

这就像从一个variables中检索值:

 VAR='test' echo VAR echo $VAR 

是不同的,所以美元符号基本上是评估内容。