I notice that to set newline IFS
should with a $ as prefix
IFS=$'\n'
but if set a colon, just
IFS=:
Is \n
is a variable?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityThat $'...'
in bash
is not parameter expansion, it's a special kind of quote introduced by ksh93
that expands those \n
, \x0a
, \12
codes to a newline character. zsh
also added \u000a
/ \U0000000a
for the characters with the corresponding Unicode code point. ksh93
and bash
also have \cj
while zsh
has \C-J
. ksh93
also supports variations like \x{a}
.
The $
is a cue that it is some form or expansion. But in any case, it differs from other forms of expansions that use $
(like $((1 + 1))
, $param
or $(cmd)
) in that it is not performed inside double quotes or here documents (echo "$'x'"
outputs $'x'
in all shells though is unspecified per POSIX) and its expansion is not subject to split+glob, it's definitely closer to a quoting operator than an expansion operator.
IFS=\n
would set IFS to n
(\
is treated as a quoting operator) and IFS="\n"
or IFS='\n'
would set IFS to the two characters backslash and n
.
You can also use:
IFS='
'
or
IFS="
"
or
IFS=$'
'
To pass a literal newline, though that's less legible (and one can't see other than using things like set list
in vi
whether $IFS
contains other spacing characters in that code).
IFS=:
, IFS=':'
, IFS=":"
, IFS=$':'
all set IFS to :
so it doesn't matter which you use.
$'...'
is supported (with variations) by at least: ksh93
, zsh
, bash
, mksh
, busybox sh
, FreeBSD sh
. ksh93
and bash
also have a $"..."
form of quotes used for localisation of text though it's rarely used as it's cumbersome to deploy and use portably and reliably.
The es
and fish
shells can also use \n
outside of quotes to expand to newline.
Some tools like printf
, some implementations of echo
or awk
can also expand those \n
by themselves. For instance, one can do:
printf '\n'
awk 'BEGIN{printf "\n"}'
echo
echo '\n\c' # UNIX compliant echos only
to output of newline character, but note that:
IFS=$(printf '\n')
won't work because command substitution ($(...)
) strips all trailing newline characters. You can however use:
eval "$(printf 'IFS="\n"')"
Which works because the output of printf
ends in a "
character, not a newline.
Now, for completeness, in the rc
shell and derivatives (like es
or akanga
), $'\n'
is indeed the expansion of that \n
variable (a variable whose name is the sequence of two characters \
and n
). Those shells don't have a limitation on what characters variable names may contain and only have one type of quotes: '...'
.
$ rc
; '\n' = (foo bar)
; echo $'\n'
foo bar
; echo $'\n'(1)
foo
rc
variables are also all exported to the environment, but at least in the Unix variant of rc
, for variable names like \n
, the environment variable version undergoes a form of encoding:
; env | grep foo | sed -n l
__5cn=foo\001bar$
(0x5c
being the byte value of ASCII \
; see also how that array variable was encoded with a 0x1 byte as the separator).
This is ANSI-C quoting:
Words of the form
$'string'
are treated specially. The word expands tostring
, with backslash-escaped characters replaced as specified by the ANSI C standard.
Thus $'\n'
is replaced by a newline.
This is unrelated to shell parameter expansion, despite the use of $
.
Strings like $'\n'
have been introduced by ksh93
and are currently not part of the POSIX standard.
They allow to use most C alike escapes, e.g. $'\u2345'
and the escapes that are also supported by echo
.
Note that if you do not like (in case of ksh93 or bash) to use that escape method, you still may use:
IFS='
'
which is equivalent but harder to read.
BTW: This extension already has passed the POSIX standard commitee, but it is scheduled for SUSv8 that is expected to appear not before the year 2020 because we first need to work on our lag behind the current list of bugs.
$'...'
expansions differ from that of echo
. They're more like the ones for the format argument of printf
. For echo
, a 0 is required in \0123
while for $'...'
and printf
format, \0123
would be \012
a newline followed by a litteral 3.
Oct 26, 2018 at 12:48
$'...'
specification is still being discussed. There are several issues still to be resolved with the currently proposed wording.
Oct 26, 2018 at 12:53
\uxxxx
expansion), and no resolution in sight that would accommodate existing implementations. So it may not make it into the next POSIX version. Maybe they could leave the \uxxxx
expansion out for issue8, so we can still have at least $'\n'
.
Oct 26, 2018 at 13:00