我需要递归地查找包含特定单词的所有文件,如果该单词存在于文件中,我需要找出该文件中的行数。我一直在尝试使用grep
,但到目前为止还没有成功。
答案1
grep -Zlr "\<THE_WORD\>" * | xargs -0 wc -l
grep 的选项:
-Z
- 用零/空字节结束打印的文件名来分隔它们(有助于处理奇怪的文件名或带有空格的文件名)-l
- 列出文件名,而不是匹配的行-r
- 递归地-i
- 忽略大小写(可选,但可能对查找所有变体有用)
在引号周围THE_WORD
,我使用了“单词分隔符”(\<
和\>
),这可以防止在“WHICH”中找到“HI”。有用,那个。
将包含“THE_WORD”的零分隔文件名列表通过管道传递给xargs
,告诉它期望零字节分隔符 ( -0
),执行wc
(字数),显示行数 ( -l
)
编辑:
要回答您在评论中的疑问,请尝试以下变体:(我已经做了一些研究!)
grep -oi "\<THE_WORD\>" /dev/null * | sort | uniq -c
以及解释:
-o
表示输出该行中的每个出现位置,因此如果您有“blah blah THE_WORD blah THE_WORD blah blah”,它将对该行输出两次,如果没有此标志,grep 只会对该行输出一次。-i
匹配大小写变体(即 The_Word、the_word 等)\<
必须是单词的开头,因此在“WHICH”中找不到“HI”。- `>' 必须以单词结尾,再次防止在 'WHICH' 中找到 'HI'
/dev/null
一个虚拟文件名,强制 grep 始终输出文件名,即使您只搜索一个文件。这可以通过使用 grep 选项来强制执行-H
,但我发现这同样简单且更具描述性,因为-H
可以被评为“鲜为人知的魔法”将所有内容通过管道进行排序(其中,呃....排序...)
将排序列表通过管道传递给 uniq,并
-c
计算排序列表中的每个出现次数
还有塔达!!
一个例子:
File example.c contains:
(*H)->segments=realloc((*H)->segments,sizeof(segment_t*)*((*H)->segment_count+1));
xenon-lornix:~/projects/emma> grep -oi "\<H\>" /dev/null *.c | sort | uniq -c
3 example.c:H
从而返回一个计数列表(3), 在哪里 (示例.c),以及什么(H)!!瞧!是啊!
另一个具有相同文件内容的:
xenon-lornix:~/projects/emma> grep -oi "\<segments\>" /dev/null example.c | sort | uniq -c
2 aa.c:segments
你可以在这里看到它找到了两个段,但没算部分。\<
&强制\>
仅匹配整个单词。 THE_WORD123
做不是匹配_THE_WORD_,分词位于非字母数字字符处。供参考。