130

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

IFS=$'\n'
  • 美元符号的确切含义是 什么?
  • 在这种特定情况下它会做什么?
  • 我在哪里可以阅读有关此特定用法的更多信息(Google 不允许在搜索中使用特殊字符,否则我不知道要查找什么)?

我知道IFS环境变量是什么,\n字符是什么(换行),但为什么不直接使用以下形式:( 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'想知道是否有人可以给我一个解释。

4

7 回答 7

168

通常bash不会解释字符串文字中的转义序列。因此,如果您写\nor "\n"or '\n',那不是换行符-它是字母n(在第一种情况下)或反斜杠后跟字母n(在其他两种情况下)。

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

于 2010-11-08T21:36:31.873 回答
24

只是为了给这个结构起一个正式的名字:形式的字符串$'...'被称为ANSI C-quoted strings

也就是说,就像在 [ANSI] C 字符串中一样,反斜杠转义序列被识别并扩展为它们的文字等价物(有关支持的转义序列的完整列表,请参见下文)。

此扩展之后,$'...'字符串的行为方式与'...'字符串相同- 即,它们被视为文字,不受任何 [进一步] shell 扩展的影响。

例如,$'\n'扩展为文字换行符 - 这是常规 bash 字符串文字(无论是'...'还是"...")无法做到的。[1]

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

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

支持的转义序列列表

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

\一个警报(铃)

\b 退格

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

\f 换页

\n 换行

\r 回车

\t 水平制表符

\v 垂直制表符

\ 反斜杠

\' 单引号

\" 双引号

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

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

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

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

\cx 一个 control-x 字符

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


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

于 2015-03-13T02:56:53.637 回答
16

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

"$'STRING'" 形式的单词以特殊方式处理。该单词扩展为一个字符串,并按照 ANSI-C 标准的规定替换反斜杠转义字符。反斜杠转义序列可以在 Bash 文档中找到。

我猜它迫使脚本将换行符转义为正确的 ANSI-C 标准。

于 2010-11-08T21:35:18.383 回答
8

重新恢复默认 IFS - 这OLDIFS=$IFS不是必需的。在 subshel​​l 中运行新的 IFS 以避免覆盖默认的 IFS:

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

此外,我真的不相信您可以完全恢复旧的 IFS。您应该将其双引号以避免换行,例如OLDIFS="$IFS".

于 2013-04-08T22:42:24.073 回答
3

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

您可以使用命令 od 测试 ANSI C 引用的字符串。

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

您可以通过输出清楚地知道含义。

于 2017-01-11T10:43:54.627 回答
0

问题:

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

简单的答案:

嘿巴什!将内部字段分隔符 (IFS)设置为新行


是什么IFS

IFS是字符,Bash 在处理字符串时用作单词/项目边界。

默认情况下,它设置为空格制表换行符的空白字符。

示例 1:

使用默认值IFS

string="first second:third forth:fifth"

for item in $string; do
    echo "$item"
done

输出:

first
second:third
forth:fifth

示例 2:

设置IFS:

# Set the IFS to collon (:) character
IFS=:

string="first second:third forth:fifth"

for item in $string; do
    echo "$item"
done

输出:

first second  
third forth  
fifth
于 2021-04-04T14:31:34.967 回答
-8

这就像从变量中检索值:

VAR='test'
echo VAR
echo $VAR

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

于 2010-11-08T21:37:01.547 回答