如何使用grep/egrep在文件中查找重复单词?

11

我需要使用egrep(或grep -e)在Unix(bash)中查找文件中的重复单词。

我尝试了:

egrep "(\<[a-zA-Z]+\>) \1" file.txt

egrep "(\b[a-zA-Z]+\b) \1" file.txt

但出于某种原因,它认为不是重复的事物却被视为重复!例如,它认为字符串“word words”符合条件,尽管有单词边界条件\>\b


为了更好地理解,请展示一些样本输入、期望输出等内容。现在我们唯一能说的就是“是的,它按照意图工作”。 - fedorqui
4个回答

9

\1匹配第一个捕获组所匹配的任何字符串。这不同于与第一个捕获组匹配相同模式。因此,即使\b位于捕获括号内,第一个捕获在单词边界上匹配的事实已不再相关。

如果您希望第二个实例也位于单词边界上,则需要明确说明:

egrep "(\b[a-zA-Z]+) \1\b" file.txt

这与以下情况没有区别:
egrep "\b([a-zA-Z]+) \1\b" file.txt

模式中的空格强制单词边界,因此我删除了多余的 \b。如果您想更明确地表达,可以将它们放入:

egrep "\<([a-zA-Z]+)\> \<\1\>" file.txt

3

我使用

pcregrep -M '(\b[a-zA-Z]+)\s+\1\b' *

检查我的文件是否存在这样的错误。如果在重复单词之间有换行符,也可以使用此方法。

解释:

  • -M, --multiline:运行多行模式(如果在重复单词之间有换行符,则非常重要)。
  • [a-zA-Z]+:匹配单词。
  • \b:单词边界,请参阅教程
  • (\b[a-zA-Z]+):将其分组。
  • \s+:匹配至少一个(但尽可能多的)空格字符。这包括换行符。
  • \1:匹配第一组中的任何内容。

1
这是预期的行为。看看man grep说了什么:

反斜杠字符和特殊表达式

符号\<和>分别匹配单词的开头和结尾的空字符串。\b符号匹配单词边缘的空字符串,而\B匹配空字符串,只要它不在单词边缘。符号\w是[[:alnum:]]的同义词,\W是[^[:alnum:]]的同义词。

然后在另一个地方我们看到了“word”的定义:

匹配控制

单词构成字符包括字母、数字和下划线。

所以这就是会产生的结果:

$ cat a
hello bye
hello and and bye
words words
this are words words
"words words"
$ egrep "(\b[a-zA-Z]+\b) \1" a
hello and and bye
words words
this are words words
"words words"
$ egrep "(\<[a-zA-Z]+\>) \1" a
hello and and bye
words words
this are words words
"words words"

-1
egrep "(\<[a-zA-Z]+>) \<\1\>" file.txt

修复了这个问题。

基本上,你需要告诉\1它也需要保持在单词边界内。


无法工作,因为\>>是不同的。(除了拼写错误之外,它与已接受的答案有何不同?)此外,请学习如何格式化代码,以便<>不被解释为HTML。请参见。 - rici

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接