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

Yan*_*ard 117 variables bash shell environment-variables ifs

如果以下示例将IFS环境变量设置为换行符...

IFS=$'\n'
Run Code Online (Sandbox Code Playgroud)
  • 什么是美元符号的意思 完全相同
  • 在这个具体案例中它做了什么?
  • 我在哪里可以阅读有关此特定用法的更多信息(Google不允许在搜索中使用特殊字符,否则我不知道该寻找什么)?

我知道IFS环境变量是什么,\n字符是什么(换行),但为什么不使用以下形式:( IFS="\n"哪个不起作用)?

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

for line in (< /path/to/file); do
    echo "Line: $line"
done
Run Code Online (Sandbox Code Playgroud)

但是,除非IFS设置为换行符,否则这将无法正常工作.为了让它工作,我必须这样做:

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

注意:我不需要另一种方式做同样的事情,我已经知道很多其他的...我只是对此感到好奇,$'\n'并想知道是否有人可以给我一个解释.

sep*_*p2k 156

通常bash不会解释字符串文字中的转义序列.所以,如果你写\n"\n"'\n',这不是一个换行符-这是字母n(在第一种情况下)或反斜杠后跟字母n(在另外两起案件).

$'somestring'带有转义序列的字符串文字语法.所以不像'\n',$'\n'实际上是一个换行符.

  • `IFS = $(echo -e'\n')`也应该以POSIX兼容的方式进行. (22认同)
  • 请注意,`$'\n'`是特定于bash的 - 它不能在POSIX shell(`/ bin/sh`)中工作.要以符合POSIX的方式获得相同的效果,可以键入`IFS ='`,然后单击return键入实际的换行符,然后键入结束`'` (15认同)
  • @Vineet - 它让我停下来对一个赞成的评论提出质疑.虽然这**是Posix-correct,但它不起作用 - bash中的命令替换运算符删除所有尾随的换行符.请参阅[此更多详细信息](http://unix.stackexchange.com/questions/17732/where-has-the-trailing-newline-char-gone-from-my-command-substitution). (11认同)
  • @DigitalTrauma我认为它甚至不是POSIX:`-e`没有定义,`\n`没有'-e`作为XSI扩展:http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo .html #tag_20_37.`printf'\n'` rocks;) (8认同)
  • 不完全是这样 - "\n"只是一个(转义)字母n.你是对的''\n'和`"\n"`是强烈的反对,然后是n. (2认同)

mkl*_*nt0 18

只是为了给构造提供正式名称:表单的字符串$'...'称为ANSI C引用的字符串.

也就是说,与[ANSI] C字符串一样,反冲时转义序列被识别并扩展到它们的文字等价物(请参阅下面的支持转义序列的完整列表).

之后这种扩张,$'...'字符串的行为方式相同'...'字符串 -也就是说,它们会被视为文字不受任何[其它] shell扩展.

例如,$'\n'扩展到面值换行符-这是一件好事一个普通的bash字符串字面量(是否'...'或者"...")不能做.[1]

另一个有趣的特性是ANSI C引用的字符串可以转义为'(单引号)\','...'(常规单引号字符串)不能:

echo $'Honey, I\'m home' # OK; this cannot be done with '...'
Run Code Online (Sandbox Code Playgroud)

支持的转义序列列表:

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

警报(铃声)

\ b退格

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

\ f表格饲料

\n换行

\ r \n回车

\ t水平标签

\ v垂直标签

\反斜杠

单引号

"双引号

\nnn八位字符,其值为八进制值nnn(一到三位数)

\ xHH八位字符,其值为十六进制值HH(一个或两个十六进制数字)

\ uHHHH Unicode(ISO/IEC 10646)字符,其值为十六进制值HHHH(一到四个十六进制数字)

\ UHHHHHHHH Unicode(ISO/IEC 10646)字符,其值为十六进制值HHHHHHHH(一到八个十六进制数字)

\ cx是control-x字符

扩展结果是单引号,好像美元符号不存在一样.


[1]但是,您可以在"..."和"..."字符串中嵌入实际换行符; 即,您可以定义跨越多行的字符串.


Bra*_*ger 16

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

"$'STRING'"形式的单词以特殊方式处理.单词扩展为一个字符串,反斜杠转义字符被ANSI-C标准指定替换.反斜杠转义序列可以在Bash documentation.found中找到

我想这是迫使脚本逃避换行符到正确的ANSI-C标准.


小智 8

重新恢复默认IFS-这OLDIFS=$IFS不是必需的.在子shell中运行新的IFS以避免覆盖默认的IFS:

ar=(123 321); ( IFS=$'\n'; echo ${ar[*]} )
Run Code Online (Sandbox Code Playgroud)

此外,我真的不相信你完全恢复旧的IFS.你应该加倍引用它以避免破线等OLDIFS="$IFS".

  • 这是一项非常有用的技术.我只是用它来做一个更干净的shell加入op:`args = $(IFS ='&'; echo"$*")`.以Bourne shell友好的方式将`IFS`恢复为'$'\ t \n'`并非易事. (2认同)