如何使用grep将包含string1和string2的所有行分隔为空格?

时间:2016-03-04 16:40:16

标签: linux grep

第1行:.................
Line2:@ hello1 @ hello2 @ hello3
第3行:.................
第4行:.................
Line5:@ hello1 @ hello4 @ hello3
Line6:@ hello1 @ hello2 @ hello3
第7行:.................

我的项目目录中的行的文件看起来类似。我想获得包含 @ hello1 @ hello2 的所有行的计数。在这种情况下,我只得到2这个文件的结果。但是,我想以递归的方式做到这一点。

4 个答案:

答案 0 :(得分:1)

“递归执行某些操作”的规范方法是使用find命令。如果你想找到有两个单词的行,一个简单的正则表达式就可以了:

grep -lr '@hello1.*@hello2' .

选项-l指示grep仅显示文件名而不是文件内容,选项-r告诉grep以递归方式遍历文件系统。搜索的开始是该行末尾的路径。获得文件列表后,可以使用xargs运行的命令解析该列表。

例如,这将计算与您指定的模式匹配的文件中的所有行。

grep -lr '@hello1.*@hello2' . | xargs -n 1 wc -l

这使用xargswc列出的每个文件上运行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}'