修改文件中的Perl搜索以仅包含指定目录

SSilk

我发现下面的代码示例在这里它搜索文件中的文本,并通过子目录递归,但是我想指定要通过其递归的第一级子目录的子集。

例如,假设我在目录中C:\包含的目录binsrc以及Windows,我想递归搜索.h.c文件包含文本“包括”,我会运行与下面的MWE,我的代码是在下面textsearch.pl

perl textsearch.pl include "(\.)(h|c)($)"

我如何修改这个程序只在搜索binsrc,但不会Windows,而在同一时间还是在递归到子目录binsrc即我希望能够执行以下操作:

perl textsearch.pl include "(\.)(h|c)($)" src,bin

我以为File::Find::Rule会有所帮助,但是在弄清楚如何在这里应用它时遇到了麻烦。

另外,如果还有另一种更简单的方法来执行所有这些操作,我很想听听。

我发现的MWE:

use strict;
use warnings;
use Cwd;

use File::Find;
use File::Basename;

my ($in_rgx,$in_files,$simple,$matches,$cwd);
sub trim($) {
  my $string = shift;
  $string =~ s/[\r\n]+//g;
  $string =~ s/\s+$//;
  return $string;
}

                                      # 1: Get input arguments
if ($#ARGV == 0) {                    # *** ONE ARGUMENT *** (search pattern)
  ($in_rgx,$in_files,$simple) = ($ARGV[0],".",1);
}
elsif ($#ARGV == 1) {                 # *** TWO ARGUMENTS *** (search pattern + filename or flag)
  if (($ARGV[1] eq '-e') || ($ARGV[1] eq '-E')) { # extended
    ($in_rgx,$in_files,$simple) = ($ARGV[0],".",0);
  }
  else { # simple
    ($in_rgx,$in_files,$simple) = ($ARGV[0],$ARGV[1],1);
  }
}
elsif ($#ARGV == 2) {                 # *** THREE ARGUMENTS *** (search pattern + filename + flag)
  ($in_rgx,$in_files,$simple) = ($ARGV[0],$ARGV[1],0);
}
else {                                # *** HELP *** (either no arguments or more than three)
  print "Usage:  ".basename($0)." regexpattern [filepattern] [-E]\n\n" .
        "Hints:\n" .
        "*) If you need spaces in your pattern, put quotation marks around it.\n" .
        "*) To do a case insensitive match, use (?i) preceding the pattern.\n" .
        "*) Both patterns are regular expressions, allowing powerful searches.\n" .
        "*) The file pattern is always case insensitive.\n";
  exit;
}


if ($in_files eq '.') {               # 2: Output search header
  print basename($0).": Searching all files for \"${in_rgx}\"... (".(($simple) ? "simple" : "extended").")\n";
}
else {
  print basename($0).": Searching files matching \"${in_files}\" for \"${in_rgx}\"... (".(($simple) ? "simple" : "extended").")\n";
}


if ($simple) { print "\n"; }          # 3: Traverse directory tree using subroutine 'findfiles'

($matches,$cwd) = (0,cwd);
$cwd =~ s,/,\\,g;
find(\&findfiles, $cwd);


sub findfiles {                       # 4: Used to iterate through each result
  my $file = $File::Find::name;       # complete path to the file

  $file =~ s,/,\\,g;                  # substitute all / with \

  return unless -f $file;             # process files (-f), not directories
  return unless $_ =~ m/$in_files/io; # check if file matches input regex
                                      # /io = case-insensitive, compiled
                                      # $_ = just the file name, no path

                                      # 5: Open file and search for matching contents
  open F, $file or print "\n* Couldn't open ${file}\n\n" && return;

  if ($simple) {                      # *** SIMPLE OUTPUT ***
    while (<F>) {
      if (m/($in_rgx)/o) {            # /o = compile regex
                 # file matched!
          $matches++;
          print "---" .               # begin printing file header
          sprintf("%04d", $matches) . # file number, padded with 4 zeros
          "--- ".$file."\n";          # file name, keep original name
                                      # end of file header
        last;                         # go on to the next file
      }
    }
  }                                   # *** END OF SIMPLE OUTPUT ***
  else {                              # *** EXTENDED OUTPUT ***
    my $found = 0;                    # used to keep track of first match
    my $binary = (-B $file) ? 1 : 0;  # don't show contents if file is bin
    $file =~ s/^\Q$cwd//g;            # remove current working directory
                                      # \Q = quotemeta, escapes string

    while (<F>) {
      if (m/($in_rgx)/o) {            # /o = compile regex
                                      # file matched!
        if (!$found) {                # first matching line for the file
          $found = 1;
          $matches++;
          print "\n---" .             # begin printing file header
          sprintf("%04d", $matches) . # file number, padded with 4 zeros
          "--- ".uc($file)."\n";      # file name, converted to uppercase
                                      # end of file header
          if ($binary) {              # file is binary, do not show content
            print "Binary file.\n";
            last;
          }
        }
        print "[$.]".trim($_)."\n";   # print line number and contents
        #last;                        # uncomment to only show first line
      }
    }
  }                                   # *** END OF EXTENDED OUTPUT ***

  # 6: Close the file and move on to the next result
  close F;
}

#7: Show search statistics
print "\nMatches: ${matches}\n";

# Search Engine Source: http://www.adp-gmbh.ch/perl/find.html
# Rewritten by Christopher Hilding, Dec 02 2006
# Formatting adjusted to my liking by Rene Nyffenegger, Dec 22 2006
伦·贾菲

find()方法第二个参数可以是要扫描的目录列表替换$cwd@some_list_of_directories,您应该会很好

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

允许Shell脚本仅修改包含目录的文件

如何复制仅包含指定类型文件的目录?

在主目录中的最近2分钟内搜索包含特定字符串的最后修改的文件

修改Perl脚本以在给定目录中为具有指定扩展名的每个文件运行

仅当文件的修改日期自此更改后才复制包含目录结构的文件

在仅包含特定目录的目录中查找不包含文件的目录

使用php仅搜索目录中的.xml.gz文件

如何遍历erlang中的目录以仅包含文件夹?

如何仅列出指定目录中的文件夹?

python中如何获取包含指定函数的文件所在目录

在Perl中,如何使用递归来搜索目录和子目录并指定深度?

在目录中搜索文件

Python递归搜索目录,仅显示包含特定字符串的文件

搜索目录时,仅显示指定文件名的第一个实例

如何在目录中搜索以某些内容开头的文件,然后获取最近修改的文件

修改工作的AddHandler以仅匹配CURRENT目录中的文件,而不匹配子目录中的文件

Windows 搜索包含给定文件的给定目录

用户在InputBox中输入文件夹名称,然后在指定目录中搜索文件夹

如何使用Java从目录中仅获取10个最后修改的文件?

仅当某些目录中的文件被修改时,才执行git pre-commit hook

如何仅同步和grep源目录中已修改文件的路径

在目录中搜索整个文件

在目录结构中搜索文件

如何使用Perl搜索和修改文件中字符串之后的浮点值

在bash中:仅当文件早于X分钟时,如何查找和删除包含特定文件的目录

仅列出目录中的文件?

仅列出目录中的文件

用于在目录中搜索单词的 Perl 脚本

Perl-扫描目录中包含的文件名和填充数组中的模式