为什么我无法将sprintf的变量字符串传递给perl脚本?

the*_*lls 3 perl printf

我带来了以下perl问题.把这段代码放到test.pl中

my $str=shift;

printf "$str", @ARGV;
Run Code Online (Sandbox Code Playgroud)

然后像这样运行:

perl test.pl "x\tx%s\n%s" one two three
Run Code Online (Sandbox Code Playgroud)

我的预期输出应该是:

x    xone
two
Run Code Online (Sandbox Code Playgroud)

相反,我得到了

x\sxone\ntwo
Run Code Online (Sandbox Code Playgroud)

我哪里错了?

Bor*_*din 8

Perl在编译时转换字符串中的转义序列,因此一旦程序运行,您就太晚了"\t","\n"转换为制表符和换行符.

使用eval会解决这个问题,但它非常不安全.我建议您String::Interpolate在编译后使用该模块处理字符串.它使用Perl的本机插值引擎,因此具有与将字符串编码到程序中完全相同的效果.

test.pl变成了

use strict;
use warnings;

use String::Interpolate qw/ interpolate /;

my $str = shift;

printf interpolate($str), @ARGV;
Run Code Online (Sandbox Code Playgroud)

产量

E:\Perl\source>perl test.pl "x\tx%s\n%s" one two three
x       xone
two
E:\Perl\source>
Run Code Online (Sandbox Code Playgroud)

更新

如果您只想允许支持的一小部分可能性,String::Interpolate那么您可以编写一些明确的内容,比如说

use strict;
use warnings;

my $str = shift;

$str =~ s/\\t/\t/g;
$str =~ s/\\n/\n/g;

printf $str, @ARGV;
Run Code Online (Sandbox Code Playgroud)

但是一个模块或者eval是在命令行上支持常规Perl字符串的唯一真正方法.