是否有可能在命令行中的perl中以printf格式获取特定参数?

时间:2016-11-07 14:22:02

标签: perl arguments printf

需要构建字符串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)

3 个答案:

答案 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 strictuse 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的双引号你无论如何都缺席了。)