如何以递归方式 grep 目录中每个文件的前 50 行?

如何以递归方式 grep 目录中每个文件的前 50 行?

我需要搜索目录及其子目录中每个文件的前 50 行。

这将执行递归部分,但如何限制每个文件的前 50 行?

grep -r "matching string here" .

有些文件非常大,我只希望匹配前 50 行。我尝试通过不搜索某些文件中的兆字节二进制数据来加快此过程。

答案1

  • 如果您只想要匹配的文件:

    find . -type f -exec bash -c 'grep -q "matching string here" < <(head -n 50 "$1")' _ {} \; -printf '%p\n'
    

    或者

    find . -type f -exec bash -c 'grep -q "matching string here" < <(head -n 50 "$1") && printf '%s\n' "$1"' _ {} \;
    
  • 如果您只想要匹配的字符串:

    find . -type f -exec head -n 50 {} \; | grep "matching string here"
    

    或更好,

    find . -type f -exec head -q -n 50 {} + | grep "matching string here"
    
  • 如果你想要两者:

    find . -type f -exec bash -c 'mapfile -t a < <(head -n 50 "$1" | grep "matching string here"); printf "$1: %s\n" "${a[@]}"' _ {} \;
    

评论。

  • sed用 代替组合可能会稍微容易一些head-- grep
  • 我要强调的是,对于可能包含奇怪符号(空格、换行符等)的文件名,所有三种方法都是 100% 安全的。
  • 对于其中两种方法,我假设您有一个较新的 bash 版本。
  • 您可以-exec ... +在每种方法中使用,但您必须自己编写内部循环!(留给读者的简单练习)。如果您有海量文件,这可能会稍微提高效率。

答案2

如果您需要与原始内容相同的 grep 输出,您可以执行以下操作:

find . -type f | while read f; do 
  if head -n 50 "$f"|grep -s "matching string here"; then
    grep "matching string here" "$f" /dev/null 
  fi
done

如果您只需要文件名,则可以用 替换第二个 grep echo "$f"

答案3

您需要组合几个不同的实用程序才能获得所需的功能。使用该find命令递归目录,查找所有文件并对head找到的每个文件执行该命令。该head命令可用于仅转储每个文件的前 50 行。最后,将输出通过管道传输到 grep 以搜索所需的字符串。

find . -type f -exec head -n 50 {} ";" | grep "matching string here"

相关内容