将perl数组拆分为qx运算符中的单独参数

时间:2014-05-10 11:07:19

标签: perl

我正在尝试将一组参数传递给qx运算符。考虑

my @files=qw(A.txt B.txt);
print qx/ls "@files"/;

这会出错:

ls: cannot access A.txt B.txt: No such file or directory

而明确地替换数组参数:

print qx/ls A.txt B.txt/;

工作正常。如何将perl数组传递给qx运算符,以使每个数组元素成为shell命令的单独参数?

2 个答案:

答案 0 :(得分:3)

删除引号,就像在shell中键入ls "A.txt B.txt"一样。

print qx/ls @files/;

警告:如果您的数组中名称中包含空格的文件,则此方法无效。你可以单独引用那些,但这听起来不是一个好主意,处理所有特殊字符肯定会在某些时候打破。在这一点上,我建议根本不使用外部程序,而是使用Perl功能。

答案 1 :(得分:3)

在您的情况下,使用

qx/ls @files/;

就够了。

@files将在qx//的参数(字符串)中进行插值,不需要将其放在字符串中。

如果@files的任何元素有空格,则qx/ls @files/将无效。例如,以下代码

my @files=('A.txt', 'B.txt', 'C .txt');
print qx/ls @files/;

会出现以下错误:

ls: .txt: No such file or directory
ls: A.txt: No such file or directory
ls: B.txt: No such file or directory
ls: C: No such file or directory

这可以通过引用@files的每个元素来解决,实现这一点的方法是

my @files=('A.txt', 'B.txt', 'C .txt');

my $files;
$files .= " \Q$_" for @files;

print qx/ls $files/;

另一种方法是使用map

my @files=('A.txt', 'B.txt', 'C .txt');
@files = map { "\Q$_" } @files;
print qx/ls @files/;

上面的代码会出现以下错误(如预期的那样)

ls: A.txt: No such file or directory
ls: B.txt: No such file or directory
ls: C .txt: No such file or directory

更新

正如@choroba所指出的,

\Q无法处理文件名中的嵌入换行符。此问题的可能解决方法\'$_\'无法处理嵌入式单引号。看起来我们需要将它们组合在一起:

my @files=('A.txt', 'B.txt', 'C .txt', "D\t.txt", "E\n.txt", "F'.txt", 'G".txt');

my $files;
$files .= m/\n/ ? " \'$_\'" : " \Q$_" for @files;

print qx/ls $files/;

这将产生以下预期错误

ls: A.txt: No such file or directory
ls: B.txt: No such file or directory
ls: C .txt: No such file or directory
ls: D\t.txt: No such file or directory
ls: E\n.txt: No such file or directory
ls: F'.txt: No such file or directory
ls: G".txt: No such file or directory