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

混江龙づ霸主 提交于 2019-11-26 18:08:33
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).

$'somestring' is a syntax for string literals with escape sequences. So unlike '\n', $'\n' actually is a linebreak.

Just to give the construct its official name: strings of the form $'...' are called ANSI C-quoted strings.

That is, as in [ANSI] C strings, backlash escape sequences are recognized and expanded to their literal equivalent (see below for the complete list of supported escape sequences).

After this expansion, $'...' strings behave the same way as '...' strings - i.e., they're treated as literals NOT subject to any [further] shell expansions.

For instance, $'\n' expands to a literal newline character - which is something a regular bash string literal (whether '...' or "...") cannot do.[1]

Another interesting feature is that ANSI C-quoted strings can escape ' (single quotes) as \', which, '...' (regular single-quoted strings) cannot:

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.


[1] You can, however, embed actual newlines in '...' and "..." strings; i.e., you can define strings that span multiple lines.

From 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

I guess it's forcing the script to escape the line feed to the proper ANSI-C standard.

Marek

Re recovering the default IFS- this OLDIFS=$IFS is not necessary. Run new IFS in subshell to avoid overriding the default 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".

ANSI C-quoted strings is a key point. Thanks to @mklement0 .

You can test ANSI C-quoted strings with command od.

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!