【问题标题】:grep - match string from the first n linesgrep - 匹配前 n 行的字符串
【发布时间】:2020-07-23 16:23:27
【问题描述】:

我正在尝试查找目录中与特定模式匹配的所有文件的名称。我编写了以下 bash 命令:

find . -type f | xargs -r -n 25 egrep -l -m 1 'pattern'

这可以正常工作并提供所需的输出。

./subdir1/file1
./subdir2/file2

但是,该模式只出现一次,并且在每个文件的前 10 行内。但是上面的命令是扫描整个文件,这不是必须的(文件很大,目录下的文件也很大,导致执行时间很长)。

我已尝试 head 每个文件的前 10 行,然后使用以下命令执行 grep:

find . -type f | xargs -r -n 25 head -n 10 egrep -l -m 1 'pattern'

但这最终会打印 10 行而不是提供匹配项。

我该怎么做?

谢谢

【问题讨论】:

  • 你可以试试awk '/pattern/ {print FILENAME; exit} NR > 10 { exit }或类似的
  • 是的,AWK 可以扫描大文件。

标签: shell grep find xargs csh


【解决方案1】:

使用 GNU awk 和 GNU 查找:

find . -type f -exec awk '/pattern/{print FILENAME; nextfile} FNR==10{nextfile}' {} +

或效率较低,因为它一次调用 awk 1 个文件,而不是像上面那样分批调用任何 awk 和任何 find:

find . -type f -exec awk '/pattern/{print FILENAME; exit} NR==10{exit}' {} \;

请注意,“模式”不是“模式”,而是regexp。 “模式”一词含糊不清,因此最好避免在这种情况下使用。

【讨论】:

    【解决方案2】:

    试试这个。

    1. 创建一个小脚本来执行head和grep
    2. 使用find 命令的-exec() 功能调用脚本

    my_script.sh:

    #!/bin/bash 
    awk -v file_name="$1" 'NR<=10{print $0, file_name}'   $1 | egrep -l -m 1 'pattern'
    

    要执行的命令:

    find . -type f -exec  ./my_script.sh {} \;
    

    在文件中搜索数字 5 的演示。

    $seq 20 | sort -nr > rev_file.txt 
    $seq 20 > file.txt 
    $cat test.ksh     
    #!/bin/ksh 
    
     awk -v file_name="$1" 'NR<=10{print $0, file_name}'   $1  | grep -w 5
    $find . -type f -exec  ./test.ksh {} \; 
     awk -v file_name="$1" 'NR<=10{print $0, file_name}'   $1  | grep -w 5 ./test.ksh
    5 ./file.txt
    $cat rev_file.txt 
    20
    19
    18
    17
    16
    15
    14
    13
    12
    11
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    $cat file.txt 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    $
    

    【讨论】:

      【解决方案3】:

      您可以通过管道连接到while 循环,而不是使用xargs。
      以下命令还使用了grep 的--quiet 开关,它只检查模式匹配并且仅 对退出代码有影响:

      find . -type f | while read -r -d'' f; do head -n10 $f | egrep -m1 --quiet 'pattern' && echo $f ; done
      

      【讨论】:

      • 谢谢。我仍然收到此错误f: Undefined variable
      • 你在 bash shell 中吗?
      • 不,我在csh
      • 我明白了。但是你用 bash 标记了你的问题。我的解决方案适用于 bash。
      • 啊,我明白了。现已更正。感谢您的回答
      猜你喜欢
      • 1970-01-01
      • 2014-03-03
      • 2015-08-17
      • 2021-09-26
      • 2011-09-16
      • 1970-01-01
      • 2011-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多