我正在尝试在perl中使用以下命令,但它给了我错误
system("zcat myfile.gz | wc > abc.txt");
但是当我运行这个时,我收到了错误 意外标记“|”
附近的语法错误即使我删除>abc.txt
,我仍然会收到错误。
我们可以使用带有系统命令的管道吗?
以下是错误详情:
sh: -c: line 1: syntax error near unexpected token `|'
sh: -c: line 1: ` | wc '
答案 0 :(得分:5)
下次,测试您的演示程序,确保它实际上展示了您所说的行为。你实际上发现了更接近
的东西while (my $file_name = <>) {
system("zcat $file_name | wc > abc.txt");
}
有两个错误:
您没有删除尾随换行符,因此shell正在尝试执行
zcat def.gz
| wc >abc.txt
而不是
zcat def.gz | wc >abc.txt
在将命令作为emded之前,您没有将文件名转换为shell文字。
考虑如果文件名包含空格会发生什么。你将执行
zcat def ghi.gz | wc >abc.txt
而不是
zcat 'def ghi.gz' | wc >abc.txt
解决方案:
use String::ShellQuote qw( shell_quote );
while (my $file_name = <>) {
chomp($file_name);
system("zcat -- ".shell_quote($file_name)." | wc > abc.txt");
}
答案 1 :(得分:1)
它按预期工作:
perl -lne 'system("cat *.java|wc");'
你的文件名可能有些奇怪,可能。
您可以像这样检查shell的插值:
my @file = `ls -1 myfile*.gz`;chomp(@files);
print join("\n",@files);
在perl中还有其他的可能性,比如反引号,用|,qx打开。
如果您遇到文件名问题,可以自己获取文件名并以特定方式调用系统以避免执行shell:http://docstore.mik.ua/orelly/perl/cookbook/ch19_07.htm
如果只有一个标量参数,则检查参数是否为shell元字符,如果有,则将整个参数传递给系统的命令shell进行解析(这是Unix平台上的/ bin / sh -c,但在其他平台上有所不同)。如果参数中没有shell元字符,它将被拆分为单词并直接传递给execvp,这样效率更高。
答案 2 :(得分:0)
当尝试使用反引号执行包含cut -d \|
命令的管道时,出现此错误消息。原来我不得不对管道字符加倍转义,例如cut -d \\|