需要构建字符串foobar is not foo and not bar
。
以printf
格式%$2s
," 2"意味着一个特定的论证位置。
但它在perl中不起作用:
$ perl -e "printf('%$1s$2s is not %$1s and not %$2s', 'foo', 'bar');"
%2 is not %1 and not %2
我的环境:
$ perl --version
This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-linux-thread-multi
(with 29 registered patches, see perl -V for more detail)
答案 0 :(得分:6)
您的报价已关闭。
perl -E 'say sprintf(q{%1$s%2$s is not %1$s and not %2$s}, "foo", "bar");'
foobar is not foo and not bar
您不能对""
使用双引号-e
,因为您的shell会混淆。你需要单引号。但是,如果您使用printf
模式的%1$s
模式使用双引号,Perl将尝试插入$s
,但这不起作用。因此,请使用非引用q{}
或使用''
转义单引号\'
。或者逃避$
s。
如果您启用use strict
和use warnings
,您会看到:
$ perl -E 'use strict; use warnings; say sprintf("%1$s%2$s is not %1$s and not %2$s", "foo", "bar");'
Global symbol "$s" requires explicit package name at -e line 1.
Global symbol "$s" requires explicit package name at -e line 1.
Global symbol "$s" requires explicit package name at -e line 1.
Global symbol "$s" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.
''
的单引号-e
和模式的双引号""
。
$ perl -E "use strict; use warnings; say sprintf('%1$s%2$s is not %1$s and not %2$s', 'foo', 'bar');"
Invalid conversion in sprintf: "%1 " at -e line 1.
Invalid conversion in sprintf: "%2" at -e line 1.
%2 is not %1 and not %2
现在,由于双引号$s
,shell试图插入""
。所以Perl从未见过它。它将模式视为"%1 %2 is not %1 and not %2"
,它无法理解。 (请注意,%
不会在Perl中的双引号字符串中进行插值。
答案 1 :(得分:2)
这适用于* nix:
perl -e "printf('%s%s is not %1\$s and not %2\$s', 'foo', 'bar');"
请参阅sprintf
documentation,特别是最后的示例:
以下是一些例子;请注意,使用显式索引时,
$
可能需要转义:printf "%2\$d %d\n", 12, 34; # will print "34 12\n" printf "%2\$d %d %d\n", 12, 34; # will print "34 12 34\n" printf "%3\$d %d %d\n", 12, 34, 56; # will print "56 12 34\n" printf "%2\$*3\$d %d\n", 12, 34, 3; # will print " 34 12\n" printf "%*1\$.*f\n", 4, 5, 10; # will print "5.0000\n"
答案 2 :(得分:1)
让我们看看您传递给perl
的程序:
$ printf '%s' "printf('%$1s$2s is not %$1s and not %$2s', 'foo', 'bar');"
printf('%ss is not %s and not %s', 'foo', 'bar');
如您所见,程序中没有$1
或$2
,因为您未正确构建shell命令。就像Perl用双引号插值一样,sh
和相关的shell也是如此。你应该使用单引号!
perl -e'printf("%\$1s\$2s is not %\$1s and not %\$2s\n", "foo", "bar");'
(我建议在Perl程序中从''
切换到q{}
,这样你就不必逃避美元符号,但你需要\n
的双引号你无论如何都缺席了。)