grep - 从前 n 行匹配字符串
grep - match string from the first n lines
我正在尝试查找目录中与特定模式匹配的所有文件的名称。我写了以下 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 行而不是提供匹配项。
我该怎么做?
谢谢
您可以通过管道传输到 while
循环,而不是使用 xargs
。
下面的命令也使用了 grep
的 --quiet
开关,它只检查模式匹配并且 只有 对退出代码有影响:
find . -type f | while read -r -d'' f; do head -n10 $f | egrep -m1 --quiet 'pattern' && echo $f ; done
试试这个。
- 创建一个小脚本来执行
head
和 grep
- 使用
find
命令的 -exec()
功能调用脚本
my_script.sh:
#!/bin/bash
awk -v file_name="" 'NR<=10{print [=10=], file_name}' | 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="" 'NR<=10{print [=12=], file_name}' | grep -w 5
$find . -type f -exec ./test.ksh {} \;
awk -v file_name="" 'NR<=10{print [=12=], file_name}' | 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
$
使用 GNU awk 和 GNU find:
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
。 “模式”一词含糊不清,因此在这种情况下最好避免使用。
我正在尝试查找目录中与特定模式匹配的所有文件的名称。我写了以下 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 行而不是提供匹配项。
我该怎么做?
谢谢
您可以通过管道传输到 while
循环,而不是使用 xargs
。
下面的命令也使用了 grep
的 --quiet
开关,它只检查模式匹配并且 只有 对退出代码有影响:
find . -type f | while read -r -d'' f; do head -n10 $f | egrep -m1 --quiet 'pattern' && echo $f ; done
试试这个。
- 创建一个小脚本来执行
head
和grep
- 使用
find
命令的-exec()
功能调用脚本
my_script.sh:
#!/bin/bash
awk -v file_name="" 'NR<=10{print [=10=], file_name}' | 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="" 'NR<=10{print [=12=], file_name}' | grep -w 5
$find . -type f -exec ./test.ksh {} \;
awk -v file_name="" 'NR<=10{print [=12=], file_name}' | 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
$
使用 GNU awk 和 GNU find:
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
。 “模式”一词含糊不清,因此在这种情况下最好避免使用。