bash IFS=$'\n' 的确切含义是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4128235/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the exact meaning of IFS=$'\n'?
提问by Yanick Girouard
If the following example, which sets the IFS
environment variable to a line feed character...
如果以下示例将IFS
环境变量设置为换行符...
IFS=$'\n'
- What does the dollar signmean exactly?
- What does it do in this specific case?
- Where can I read more on this specific usage (Google doesn't allow special characters in searches and I don't know what to look for otherwise)?
- 什么是美元符号的意思 完全相同?
- 在这种特定情况下它有什么作用?
- 我在哪里可以阅读有关此特定用法的更多信息(Google 不允许在搜索中使用特殊字符,否则我不知道要查找什么)?
I know what the IFS
environment variable is, and what the \n
character is (line feed), but why not just use the following form:
IFS="\n"
(which does not work)?
我知道IFS
环境变量是什么,\n
字符是什么(换行),但为什么不使用以下形式:(
IFS="\n"
这不起作用)?
For example, if I want to loop through every line of a file and want to use a for loop, I could do this:
例如,如果我想遍历文件的每一行并想使用 for 循环,我可以这样做:
for line in (< /path/to/file); do
echo "Line: $line"
done
However, this won't work right unless IFS
is set to a line feed character. To get it to work, I'd have to do this:
但是,除非IFS
设置为换行符,否则这将无法正常工作。为了让它工作,我必须这样做:
OLDIFS=$IFS
IFS=$'\n'
for line in (< /path/to/file); do
echo "Line: $line"
done
IFS=$OLDIFS
Note:I don't need another way for doing the same thing, I know many other already... I'm only curious about that $'\n'
and wondered if anyone could give me an explanation on it.
注意:我不需要另一种方式来做同样的事情,我已经知道很多其他的......我只是对此感到好奇,$'\n'
想知道是否有人可以给我一个解释。
回答by sepp2k
Normally bash
doesn't interpret escape sequences in string literals. So if you write \n
or "\n"
or '\n'
, that's not a linebreak - it's the letter n
(in the first case) or a backslash followed by the letter n
(in the other two cases).
通常bash
不解释字符串文字中的转义序列。因此,如果您写\n
or"\n"
或'\n'
,那不是换行符 - 它是字母n
(在第一种情况下)或反斜杠后跟字母n
(在其他两种情况下)。
$'somestring'
is a syntax for string literals with escape sequences. So unlike '\n'
, $'\n'
actually is a linebreak.
$'somestring'
是带有转义序列的字符串文字的语法。所以不像'\n'
,$'\n'
实际上是一个换行符。
回答by mklement0
Just to give the construct its official name: strings of the form $'...'
are called ANSI C-quoted strings.
只是为了给这个结构起一个正式的名字:这种形式的字符串$'...'
被称为ANSI C 引用的字符串。
That is, as in [ANSI] C strings, backlash escape sequencesare recognized and expanded to their literal equivalent(see below for the complete list of supported escape sequences).
也就是说,就像在 [ANSI] C 字符串中一样,反冲转义序列被识别并扩展为它们的文字等价物(有关支持的转义序列的完整列表,请参见下文)。
Afterthis expansion, $'...'
strings behave the same way as '...'
strings- i.e., they're treated as literalsNOT subject to any [further] shell expansions.
在此扩展之后,$'...'
字符串的行为方式与'...'
字符串相同- 即,它们被视为不受任何 [进一步] shell 扩展约束的文字。
For instance, $'\n'
expands to a literal newline character - which is something a regular bash string literal (whether '...'
or "..."
) cannot do.[1]
例如,$'\n'
扩展为文字换行符 - 这是常规 bash 字符串文字(无论'...'
或"..."
)不能做的事情。[1]
Another interesting feature is that ANSI C-quoted strings can escape '
(single quotes) as \'
, which, '...'
(regular single-quoted strings) cannot:
另一个有趣的特性是ANSI C 引用的字符串可以将'
(单引号)转义为\'
,而'...'
(常规单引号字符串)不能:
echo $'Honey, I\'m home' # OK; this cannot be done with '...'
List of supported escape sequences:
支持的转义序列列表:
Backslash escape sequences, if present, are decoded as follows:
\a alert (bell)
\b backspace
\e \E an escape character (not ANSI C)
\f form feed
\n newline
\r carriage return
\t horizontal tab
\v vertical tab
\ backslash
\' single quote
\" double quote
\nnn the eight-bit character whose value is the octal value nnn (one to three digits)
\xHH the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
\uHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)
\UHHHHHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)
\cx a control-x character
The expanded result is single-quoted, as if the dollar sign had not been present.
反斜杠转义序列(如果存在)按如下方式解码:
\a 警报(响铃)
\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] You can, however, embed actualnewlines in '...' and "..." strings; i.e., you can define strings that span multiple lines.
[1] 但是,您可以在 '...' 和 "..." 字符串中嵌入实际的换行符;即,您可以定义跨越多行的字符串。
回答by Brad Swerdfeger
From http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html:
来自http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html:
Words in the form "$'STRING'" are treated in a special way. The word expands to a string, with backslash-escaped characters replaced as specified by the ANSI-C standard. Backslash escape sequences can be found in the Bash documentation.found
"$'STRING'" 形式的单词以特殊方式处理。该单词扩展为字符串,并按照 ANSI-C 标准的规定替换反斜杠转义字符。反斜杠转义序列可以在 Bash 文档中找到。found
I guess it's forcing the script to escape the line feed to the proper ANSI-C standard.
我想这是迫使脚本将换行符转义为正确的 ANSI-C 标准。
回答by Marek
Re recovering the default IFS- this OLDIFS=$IFS
is not necessary. Run new IFS in subshell to avoid overriding the default IFS:
重新恢复默认 IFS - 这OLDIFS=$IFS
不是必需的。在子 shell 中运行新的 IFS 以避免覆盖默认 IFS:
ar=(123 321); ( IFS=$'\n'; echo ${ar[*]} )
Besides I don't really believe you recover the old IFS fully. You should double quote it to avoid line breaking such as OLDIFS="$IFS"
.
此外,我真的不相信您完全恢复了旧的 IFS。您应该将其双引号以避免换行,例如OLDIFS="$IFS"
.
回答by Big Shield
ANSI C-quoted strings is a key point. Thanks to @mklement0 .
ANSI C 引用的字符串是一个关键点。感谢@mklement0。
You can test ANSI C-quoted strings with command od.
您可以使用命令 od 测试 ANSI C 引用的字符串。
echo -n $'\n' | od -c
echo -n '\n' | od -c
echo -n $"\n" | od -c
echo -n "\n" | od -c
Outputs:
输出:
0000000 \n
0000001
0000000 \ n
0000002
0000000 \ n
0000002
0000000 \ n
0000002
You can know the meaning clearly by the outputs.
您可以通过输出清楚地知道含义。
回答by Pieter
It's like retrieving the value from a variable:
这就像从变量中检索值:
VAR='test'
echo VAR
echo $VAR
are different, so the dollar sign basically evaluates the content.
不同,所以美元符号基本上是评价内容的。