繁体   English   中英

Escaping perl 中的括号 bash 命令的反引号

[英]Escaping parentheses in perl backticks for bash command

多年来我一直在使用反引号,但这是我第一次尝试使用带括号的命令。 我收到一个我无法弄清楚的错误。

我试过在多个地方用双引号和 escaping 加上\ ,但似乎没有任何效果。 任何帮助,将不胜感激。

命令$file5$file6是 perl 变量,而不是 bash。

@array = `/usr/bin/join -j 1 -t, <(cat $file5 | awk -F, '{print \$3","\$1}' | sort) <( cat $file6 | awk -F, '{print \$3","\$1}' | sort) `

错误:AH01215:sh:-c:第 0 行:意外标记“(”附近的语法错误,引荐来源:

反引号使用/bin/sh ,虽然<(... )bash识别,但 bourne shell 无法识别。如果您使用反引号,则需要使用

my $bash_cmd = ...;
my @lines = `bash -c $bash_cmd`;

构建shbash shell 命令可以使用String::ShellQuote完成。

use String::ShellQuote qw( shell_quote );

my $file5_quoted = shell_quote($file5);
my $file6_quoted = shell_quote($file6);

my $awk_cmd = shell_quote("awk", "-F,", '{print $3","$1}');

my $bash_cmd = '/usr/bin/join -j 1 -t,'
   . " <( $awk_cmd $file5_quoted | sort )"
   . " <( $awk_cmd $file6_quoted | sort )";

my $sh_cmd = shell_quote("bash", "-c", $bash_cmd);
my @lines = `$sh_cmd`;

我们可以使用IPC::System::Simplecapturex来避免启动比需要更多的 shell,并提供错误检查。 为此,将上面的最后两行替换为以下内容:

use IPC::System::Simple qw( capturex );

my @lines = capturex("bash", "-c", $bash_cmd);

一种解决方法是创建一个 shell 脚本,它接受来自 perl 的两个文件名,使用这两个输入文件处理连接,并将结果返回到 perl 数组。

#1. Create join.sh that contains these four lines:

    cat $1 | awk -F, '{print $3","$1}' | sort > 1.out
    cat $2 | awk -F, '{print $3","$1}' | sort > 2.out
    /usr/bin/join -j 1 -t, 1.out 2.out
    rm 1.out 2.out


#2. Modify your perl statement to call join.sh as follows:

    @array=`join.sh $file5 $file6`;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM