When to Use Bash ANSI C Style Escape, e.g. $’\n’

escape-charactersnewlinesquoting

I don't use bash often but I recall in the past to pass a tab or newline on the command line I would have to escape the character using the special $ character before a single quoted string. Like $'\t', $'\n', etc. I had read about quotes and escaping in the bash manual.

What I want to know is when it's appropriate to use an ANSI C style escape. For example I was working with a regex in grep and it appeared I needed an ANSI C style escape for a newline. Then I switched to perl and it seemed I didn't.

Take for example my recent question on stackoverflow about a perl regex that didn't work. Here's the regex I was using:

echo -e -n "ab\r\ncd" | perl -w -e $'binmode STDIN;undef $/;$_ = <>;if(/ab\r\ncd/){print "test"}'

It turns out that is actually incorrect because I gave the string ANSI C style escape by using $. I just don't understand when I'm supposed to prepend the dollar sign and when I'm not.

Best Answer

You use $'...' when you want escape sequences to be interpreted by the shell.

$ echo 'a\nb'
a\nb

$ echo $'a\nb'
a
b

In perl, -e option get a string. If you use $'...', the escape sequences in string are interpreted before passing to perl. In your case, \r had gone and never passed to perl.

With $'...':

$ perl -MO=Deparse -we $'binmode STDIN;undef $/;$_ = <>;if(/ab\r\ncd/){print "test"}'
BEGIN { $^W = 1; }
binmode STDIN;
undef $/;
$_ = <ARGV>;
if (/ab\ncd/) {
    print 'test';
}
-e syntax OK

Without it:

$ perl -MO=Deparse -we 'binmode STDIN;undef $/;$_ = <>;if(/ab\r\ncd/){print "test"}'
BEGIN { $^W = 1; }
binmode STDIN;
undef $/;
$_ = <ARGV>;
if (/ab\r\ncd/) {
    print 'test';
}
-e syntax OK
Related Question