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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:51:00  来源:igfitidea点击:

What is the exact meaning of IFS=$'\n'?

bashshellvariablesenvironment-variablesifs

提问by Yanick Girouard

If the following example, which sets the IFSenvironment 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 IFSenvironment variable is, and what the \ncharacter 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 IFSis 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 bashdoesn't interpret escape sequences in string literals. So if you write \nor "\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不解释字符串文字中的转义序列。因此,如果您写\nor"\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=$IFSis 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.

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