【问题标题】:Executing shell command with pipe in perl在perl中使用管道执行shell命令
【发布时间】:2014-05-20 04:54:52
【问题描述】:

我希望在 perl 脚本的变量中捕获 shell 命令的输出,只有管道“|”之前的命令的第一部分正在执行,执行脚本时没有错误

File.txt 
Error input.txt got an error while parsing 
Info  output.txt has no error while parsing 

my $var = `grep Error ./File.txt | awk '{print $2}'`;
print "Errored file $var";

Errored file Error input.txt 在解析时出错

我只想要被 awk 命令过滤但没有发生的 input.txt。请帮忙

【问题讨论】:

    标签: perl shell


    【解决方案1】:

    $2 中的$ 是由 Perl 插值的,所以 shell 接收到的命令如下所示:

    grep Error ./File.txt | awk '{print }'
    

    (如果您最近将正则表达式与捕获组匹配,则为其他内容)。解决方法是转义美元符号:

    my $var = `grep Error ./File.txt | awk '{print \$2}'`
    

    【讨论】:

      【解决方案2】:

      在每个 perl 脚本中始终包含 use strict;use warnings;

      如果你有,你会收到以下警告:

      Use of uninitialized value $2 in concatenation (.) or string at scratch.pl line 4.
      

      这会提醒您命令中的问题,即 $2 变量正在被插值而不是被视为文字。

      有三种方法可以避免这种情况。

      1) 你可以按照mob 的建议去做,然后避开 $2

      my $var = `grep Error ./File.txt | awk '{print \$2}'`
      

      2) 您可以使用带有单引号的qx 形式的反引号,这样它就不会进行插值,尽管这不太理想,因为您在命令中使用了单引号:

      my $var = qx'grep Error ./File.txt | awk \'{print $2}\''
      

      3) 您可以只使用纯 perl 解决方案。

      use strict;
      use warnings;
      
      my ($var) = do {
          local @ARGV = 'File.txt';
          map {(split ' ')[1]} grep /Error/, <>;
      };
      

      【讨论】:

        最近更新 更多