【问题标题】:using egrep in perl and travel through the directories在 perl 中使用 egrep 并遍历目录
【发布时间】:2019-06-16 21:23:45
【问题描述】:

我有一个目录,在那个目录里面我有 x 个子目录,在每个子目录里面我有很多文件和文件夹,这里我需要用 grep 搜索一个特定的关键字,比如“XYZ”,然后把结果放在文本文件中完整路径。

如何打开子目录下的每个文件(我不知道文件名,因为我是从 git 克隆的)并搜索特定的关键字。

下面是我的代码快照 我使用 egrep 命令,但在这里我没有得到完整路径(完整路径应该是(/dir/sub/file/)

因为我是编码新手,所以我需要一些输入。谢谢

$path1="/nfs/pais/abh/pgm4.txt";

foreach my $file ( glob('/nfs/abc/*') )

{
        if(-d $file){
        chdir ("$file") or die "cannot change";
    print(cwd); my $cmd = "egrep -nre 'Non' *.*  ";
    `egrep -nre 'nemu' *.* >> $path1` ;
    `egrep -nre 'ELATION' *.* >> $path1` ;
    `egrep -nre 'EULATION' *.* >> $path1` ;


}

【问题讨论】:

    标签: perl unix


    【解决方案1】:

    您不需要多次运行 egrep...您可以只用一个 egrep 来完成,甚至最好用几行 Perl 来完成。

    您只需要使用完整路径open 文件,然后对于文件中的每一行(使用<$fh> 读入),您可以使用正则表达式查找匹配的行并print 他们你的输出文件。

    open(my $output,">","/nfs/pais/abh/pgm4.txt") || die;
    
    if(open(my $fh,"<","/net/abc/$file"))
      {
      while(<$fh>)
        {
        if( /Nonemu|EMULATION|INTEL_EMULATION/)
          {
          print $output $_;
          }
        }
      close($fh);
      }
    

    此外,像这样使用chdir 也不是一个好主意,因为它首先假定您在正确的起始目录中,但它也不会“撤消”目录更改,因此将无法在下一个子目录。

    如果要遍历多层子目录,则需要编写递归子(例程)。

    【讨论】:

      【解决方案2】:

      使用您的perl 脚本,您没有使用perl 的模式匹配功能。可以在不使用egrep 的情况下对perl 中的所有内容进行编程。

      但我认为find 与egrep 结合使用更容易。

      find /nfs/abc -type f -exec egrep -ne 'XYZ' {} /dev/null \;
      

      【讨论】:

      • find /nfs/abc -type f -exec egrep -Hne 'XYZ' {} + 可能是该解决方案的更好版本。大多数时候,差异是微不足道的,但是如果目录很大,它可以提供显着的性能改进(它在文件组上调用 egrep,因此它执行的 fork/exec 次数要少得多,并且即使有命令行上只有一个文件。)
      【解决方案3】:

      由于这里有perl标签,所以我想我会给出一个perl答案:

      #!/usr/bin/perl
      
      use strict;
      use warnings;
      
      use File::Find;
      
      sub file_check {
          open my $FH, '<', $_ or return;
          while (<$FH>) {
              if (/Non|nemu|EU?LATION/) {
                  print "$File::Find::name: $_";
              }
          }
          close $FH;
      }
      
      my $path1 = "/nfs/pais/abh/pgm4.txt";
      open my $OUT, '>', $path1
      or die "$0: cannot write to $path1: $!\n";
      
      File::Find::find(\&file_check </nfs/abc/*>);
      

      诚然,这是对更改目录失败的沉默,而不是在没有上下文的情况下给出致命错误。 File::Find 实际上并没有提供一个挂钩来执行此操作,甚至没有提供 unix find 命令会给出的警告。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-29
        • 2010-11-09
        • 2013-11-04
        • 2021-07-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多