第1行:.................
Line2:@ hello1 @ hello2 @ hello3
第3行:.................
第4行:.................
Line5:@ hello1 @ hello4 @ hello3
Line6:@ hello1 @ hello2 @ hello3
第7行:.................
我的项目目录中的行的文件看起来类似。我想获得包含 @ hello1 和 @ hello2 的所有行的计数。在这种情况下,我只得到2这个文件的结果。但是,我想以递归的方式做到这一点。
答案 0 :(得分:1)
“递归执行某些操作”的规范方法是使用find
命令。如果你想找到有两个单词的行,一个简单的正则表达式就可以了:
grep -lr '@hello1.*@hello2' .
选项-l
指示grep仅显示文件名而不是文件内容,选项-r
告诉grep以递归方式遍历文件系统。搜索的开始是该行末尾的路径。获得文件列表后,可以使用xargs
运行的命令解析该列表。
例如,这将计算与您指定的模式匹配的文件中的所有行。
grep -lr '@hello1.*@hello2' . | xargs -n 1 wc -l
这使用xargs
在wc
列出的每个文件上运行grep
命令。您可能也可以在没有-n 1
的情况下运行它,除非您处理的数千个文件超出了最大命令行长度。
或者,如果我正确地解释您的问题,以下内容将只计算这些文件中的模式。
grep -lr '@hello1.*@hello2' . | xargs -n 1 grep -Hc '@hello1.*@hello2'
它运行与用于生成递归文件列表的grep类似的grep,并使用文件名(-H
)和count(-c
)显示输出。
但是如果你想要复杂的规则,比如在文件中的不同行上找到两个模式,那么grep
可能不是最佳工具,除非你使用由find
启动的多个greps:
find /path/to/base -type f \
-exec grep -q '@hello1' {} \; \
-exec grep -q '@hello2' {} \; \
-print
(线条分开以便于阅读。)
这有点贵,因为find
需要为每个文件启动最多两个孩子。所以另一种方法是使用awk代替:
find /path/to/base -type f \
-exec awk '/@hello1/{c++} /@hello2/{c++} c==2{r=1} END{exit 1-r}' {} \; \
-print
或者,如果您的shell为bash
版本4或更高版本,则可以避免使用find
并使用bash选项globstar
:
$ shopt -s globstar
$ awk 'FNR=1{c=0} /@hello1/{c++} /@hello2/{c++} c==2{print FILENAME;nextfile}' **/*
注意:这些都没有经过测试。
答案 1 :(得分:0)
如果您对文件数量不感兴趣, 然后就是这样:
find $BASEDIRECTORY -type f -print0 | xargs -0 grep -h PATTERN | wc -l
答案 2 :(得分:0)
如果您想计算在特定文件中以空格分隔的包含@hello1
和@hello2
的行,您可以:
$ grep -c '@hello1 @hello2' file
如果您想要计入多个文件:
$ grep -c '@hello1 @hello2' file1 file2 ...
如果你想获得总数:
$ grep -c '@hello1 @hello2' file1 file2 ... | paste -s -d+ - | bc
当然你可以让你的shell扩展文件名。所以,例如:
$ grep -c '@hello1 @hello2' *.txt | paste -s -d+ - | bc
左右......
答案 3 :(得分:0)
find . -type f | xargs -1 awk '/@hello1/ && /@hello2/{c++} END{print FILENAME, c+0}'