如果以下示例将IFS
环境变量设置为换行符...
IFS=$'\n'
我知道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'
感到好奇,并想知道是否有人可以给我一个解释。
答案 0 :(得分:150)
通常bash
不解释字符串文字中的转义序列。因此,如果你写\n
或"\n"
或'\n'
,那不是一个换行符 - 它是字母n
(在第一种情况下)或反斜杠后跟字母{{ 1}}(在另外两种情况下)。
n
是带有转义序列的字符串文字的语法。与$'somestring'
不同,'\n'
实际上是一个换行符。
答案 1 :(得分:17)
只需为构造提供正式名称:$'...'
形式的字符串称为 ANSI C-quoted strings 。
也就是说,与[ANSI] C字符串中一样,反向间隙转义序列被识别,扩展到它们的字面等价(有关支持的转义序列的完整列表,请参见下文) )。
此扩展后,$'...'
字符串的行为方式与'...'
字符串相同 - 即,它们被视为 文字不受任何[进一步] shell扩展的影响。
例如,$'\n'
扩展为文字换行符 - 这是常规bash字符串文字(无论'...'
还是"..."
)无法做到的事情。 [1] < / SUP>
另一个有趣的功能是 ANSI C引用的字符串可以将'
(单引号)转义为\'
,'...'
(常规单引号)字符串)不能:
echo $'Honey, I\'m home' # OK; this cannot be done with '...'
支持的转义序列列表:
反斜杠转义序列(如果存在)按如下方式解码:
\一个 警报(铃声)
\ b 退格
。\ E 。\ E 转义字符(不是ANSI C)
\˚F 形式饲料
\ n 换行
\ r 回车
\吨 水平标签
符\ v 垂直标签
\ 反斜杠
\&#39; 单引号
\&#34; 双引号
\ NNN 八位字符,其值为八进制值nnn(一到三位数)
\ XHH 八位字符,其值为十六进制值HH(一个或两个十六进制数字)
\ Joey:嗯 Unicode(ISO / IEC 10646)字符,其值为十六进制值HHHH(一到四个十六进制数字)
\ UHHHHHHHH Unicode(ISO / IEC 10646)字符,其值为十六进制值HHHHHHHH(一到八个十六进制数字)
\ CX 一个control-x字符
展开的结果是单引号,好像美元符号不存在一样。
[1]但是,您可以在&#39; ...&#39;中嵌入实际换行符。和&#34; ...&#34;串;即,您可以定义跨越多行的字符串。
答案 2 :(得分:16)
来自http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html:
“$'STRING'”形式的单词是 以特殊的方式对待。这个单词 扩展为一个字符串,用 替换了反斜杠转义的字符 按ANSI-C标准规定。 反斜杠转义序列可以 在Bash documentation.found
中找到
我猜这是迫使脚本将换行转换为正确的ANSI-C标准。
答案 3 :(得分:8)
重新恢复默认IFS-此OLDIFS=$IFS
不是必需的。在子shell中运行新的IFS以避免覆盖默认的IFS:
ar=(123 321); ( IFS=$'\n'; echo ${ar[*]} )
此外,我真的不相信你完全恢复旧的IFS。你应该加倍引用它以避免换行,例如OLDIFS="$IFS"
。
答案 4 :(得分:2)
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
您可以通过输出清楚地了解其含义。
答案 5 :(得分:0)
IFS=$'\n'
的确切含义是什么?
嘿巴什!将内部字段分隔符 (IFS) 设置为新行
IFS
?IFS
是字符,Bash 在处理字符串时用作词/项边界。
设置为空格、制表符和换行的空白字符,默认。>
对 IFS
使用默认值
string="first second:third forth:fifth"
for item in $string; do
echo "$item"
done
输出:
first
second:third
forth:fifth
将 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
答案 6 :(得分:-6)
就像从变量中检索值一样:
VAR='test'
echo VAR
echo $VAR
是不同的,所以美元符号基本上评估内容。