【问题标题】:How do I use Perl on the command line to search the output of other programs?如何在命令行中使用 Perl 搜索其他程序的输出?
【发布时间】:2010-10-02 23:11:47
【问题描述】:

据我所知(Perl 对我来说是新手)Perl 可用于针对 Unix 命令行编写脚本。我想要做的是运行(硬编码)命令行调用,并在这些调用的输出中搜索 RegEx 匹配项。有没有办法在 Perl 中简单地做到这一点?怎么样?

编辑:这里的顺序是: - 调用另一个程序。 - 对其输出运行正则表达式。

【问题讨论】:

    标签: perl unix command-line


    【解决方案1】:
    my $command = "ls -l /";
    my @output = `$command`;
    for (@output) {
        print if /^d/;
    }
    

    qx// 准引用运算符(反引号是一种快捷方式)是从 shell 语法中窃取的:在新 shell 中将字符串作为命令运行,并返回其输出(作为字符串或列表,具体取决于语境)。详情请见perlop

    你也可以打开管道:

    open my $pipe, "$command |";
    while (<$pipe>) {
        # do stuff
    }
    close $pipe;
    

    这使您可以 (a) 避免将整个命令的输出一次收集到内存中,并且 (b) 让您可以更好地控制命令的运行。例如,您可以避免命令被 shell 解析:

    open my $pipe, '-|', @command, '< single argument not mangled by shell >';
    

    有关详细信息,请参阅perlipc

    【讨论】:

    • 或者当我最终实现它时: for (@output) { my_action() if /regex/; } 如果我受到打击,允许我做任何我想做的事。谢谢!
    【解决方案2】:

    正如其他人所提到的,没有 Perl 你也许可以逃脱惩罚。但是,如果您需要一些 Perl 功能,例如扩展的正则表达式功能或额外的文本操作,您可以将输出通过管道传输到 perl,然后执行您需要的操作。 Perl 的-e 开关让我们在命令行中指定 Perl 程序:

    command | perl -ne 'print if /.../'
    

    您可以将其他几个开关传递给 perl 以使其在命令行上非常强大。这些记录在perlrun 中。还可以查看Randal Schwartz's Unix Review column 中的一些文章,尤其是他的first article for them。你也可以googlePerl one liners找到很多例子。

    【讨论】:

    • 这里没有省略 -n 标志吗?
    【解决方案3】:

    你需要 Perl 吗?怎么样

    command -I use | grep "myregexp" && dosomething
    

    就在shell中?

    【讨论】:

    • 这将发生数百次,我将添加一个输出文件,所以是的。但是您的命令与 Perl 将发出的命令非常相似:P
    • 对于输出文件,“tie”。但是数百次......可能是 Perl。
    【解决方案4】:
    #!/usr/bin/perl
    
    sub my_action() {
            print "Implement some action here\n";
    }
    
    open PROG, "/path/to/your/command|" or die $!;
    while (<PROG>) {
            /your_regexp_here/ and my_action();
            print $_;
    }
    close PROG;
    

    这将扫描您的命令的输出,匹配正则表达式并执行一些操作(现在正在打印该行)

    【讨论】:

    • 也许用 do 块替换 print 语句会更好。
    • 这不会运行任何所需的“(硬编码)命令行调用”,它只是读取并作用于标准输入。
    【解决方案5】:

    在 Perl 中,您可以使用反引号在 shell 上执行命令。这是document on using backticks。我不确定如何捕获输出,但我确信不只是一种方法

    【讨论】:

      【解决方案6】:

      在这种情况下,您确实使用了单线。我最近编写了一个代码,我使用它来生成输出,其中列出了 .zip 存档中存在的目录结构(每行一个目录条目)。因此,使用该输出作为我们想要过滤的命令输出示例,我们可以放入一个管道,然后使用带有-n -e 标志的 perl 来过滤传入的数据(和/或用它做其他事情):

      [command_producing_text_output] | perl -MFile::Path -n -e \
         "BEGIN{@PTM=()} if (m{^perl/(bin|lib(?!/site))}) {chomp;push @PTM,$_}" ^
      -e "END{@WDD=mkpath (\@PTM,1);" ^
      -e "printf qq/Created %u dirs to reflect part of structure present in the .ZIP file\n/, scalar(@WDD);}"
      

      使用的 shell 语法,包括:perl 代码的引用和换行符的转义,反映了 CMD.exe 在类似 Windows NT 的控制台中的使用。如果需要,请在精神上更换 "^" 与 "\" 和 " 与 ' 在适当的地方。

      上面的单行只添加以“perl/bin”或开头的目录名 "perl/lib (后面不跟 "/site"); 然后它会创建这些目录。 制作一棵(空)树,您可以将其用于您想要的任何邪恶目的。

      主要是说明有可用的标志(-n-p) 允许 perl 循环遍历每个输入记录(行),并且您可以做的事情在复杂性方面是无限的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-23
        • 1970-01-01
        • 2021-10-24
        • 2012-09-09
        • 2011-09-13
        • 2010-11-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多