通过专门的输出,帮助在文件中递归地搜索正则表达式模式

通过专门的输出,帮助在文件中递归地搜索正则表达式模式

我的问题是我需要:

  1. 查找regex_pattern给定根目录中所有文件中匹配的所有行(深度搜索)
  2. 对于匹配的每一行,输出:
    • 文件名
    • 包含匹配项的行号
    • 行内容
    • 正则表达式模式
  3. 将上述数据导入 Excel(因此会想到 CSV 或分隔输出格式)

完成这项任务最简单的方法是什么?

为了证明我对此有所思考,我会编写一个 Perl 脚本,该脚本将单个完全限定的文件名和正则表达式模式作为输入,并使用下面的近似 Perl 处理这些行(我还没有尝试过,但是这个这就是我的第一次尝试):

while (<FILE>) {
  $line_number++;

  if ($_ =~ m/regex_pattern/) {
    # output: file_name\tline_number\tregex_pattern\t$_
    # ignore escaping issues for the time being
  }
}

我仍然不确定如何通过递归搜索传递每个目录的内容到这个 Perl 脚本中。我可以在 Perl 中进行搜索,但我确信有一种很好的 Unix/Linux 方法可以做到这一点。

我没有和 Perl 结婚。如果有一种方法可以将标准 Unix/Linux 工具链接在一起,那就太棒了。如果没有,我更喜欢使用 Perl,因为我对它的语法有些熟悉。

答案1

像这样的东西吗?

find /search/root -type f -exec awk 'BEGIN{pattern="regex_pattern"} $0 ~ pattern {printf "%s,%s,%s,%s\n",FILENAME,FNR,$0,pattern}'  {} +

答案2

start cmd:> find . -type f -name 'search*' -exec awk -v regex=foo \
cont. cmd:>   '$0 ~ regex {print FILENAME,FNR,regex,$0 }' {} +
./searchfile1 1 foo a_foo_b
./searchfile2 1 foo foo

答案3

在 Perl 中,利用空文件句柄它对命令行参数进行操作:

#!/usr/bin/perl -n
$, = "\t";  # separator added between arguments to print
while (<>) {
  if (/regex_pattern/) {
    # $ARGV contains the current file name, $. contains the current line number,
    # $_ contains the current line including its terminating newline
    print $ARGV, $., 'regex_pattern', $_;
  }
  $. = 0 if eof;  # reset the line number between files
}

要将文件名传递给 Perl 脚本,在 ksh93 或 bash ≥4 或 zsh 中,您可以使用**图案递归遍历子目录。在 ksh 中,您需要首先使用 启用此模式set -o globstar。在 bash 中,您需要使用 来启用它shopt -s globstar

shopt -s globstar
name_of_perl_script **/*

如果您的 shell 没有**,或者遇到“命令行太长”错误,您可以使用find

find . -type f -exec name_of_perl_script {} +

您还可以通过组合更专业的工具来做到这一点。您可能已经知道 grep 来搜索文件中的模式。该-n选项使其打印每个匹配行的编号。作为文件名传递/dev/null是确保grep也打印文件名的技巧(如果命令行上碰巧有单个文件,则不会执行此操作)。

grep -n 'regex_pattern' **/*

所缺少的只是在必要时更改分隔符(在文件名、行号和行内容之间grep插入),并在正确的位置插入正则表达式。:这个简单的替换工作非常适合sed。请务必正确引用正则表达式。

find . -type f -exec grep -n 'regex_pattern' {} + |
sed 's/^\([^:]*\)\([^:]*\)/\1\t\2\tregex_pattern\t/'

相关内容