何时使用 bash ANSI C 风格转义,例如 $'\n'

何时使用 bash ANSI C 风格转义,例如 $'\n'

我不经常使用 bash,但我记得过去在命令行上传递制表符或换行符时,我必须$在单引号字符串之前使用特殊字符来转义字符。比如$'\t'$'\n'等等,我读过bash 手册中的引号和转义。

我想知道什么时候适合使用 ANSI C 风格转义。例如,我正在 grep 中使用正则表达式,似乎我需要 ANSI C 样式转义来换行。然后我就改用perl了,看来我没有。

举个例子我最近在 stackoverflow 上提出的问题关于一个不起作用的 Perl 正则表达式。这是我使用的正则表达式:

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

事实证明这实际上是不正确的,因为我通过使用 给了字符串 ANSI C 风格转义$。我只是不明白什么时候应该在前面加上美元符号,什么时候不应该。

答案1

$'...'当您希望 shell 解释转义序列时使用。

$ echo 'a\nb'
a\nb

$ echo $'a\nb'
a
b

在 中perl-e选项获取一个字符串。如果使用$'...',则在传递给 之前解释 string 中的转义序列perl。就你而言,\r已经消失并且从未传递到perl

$'...'

$ 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

没有它:

$ 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

答案2

$'\n'与打字基本相同Enter

所以在你的 Perl 例子中,它变成*

  if(/ab
cd/)

这不是你想要的。

我能想到使用的原因$'...'

  • 您想在单引号分隔的字符串中放入单引号,例如logger $'Can\'t open file'
  • 使不可打印的字符更清晰,例如$'a\tb'而不是'a<TAB character>b'

(不确定是否\r\n被视为等同于\n或 Perl 是否看到回车+换行符,但无论哪种情况,都不是您想要的。)

相关内容