我需要使用egrep(或grep -e)在Unix(bash)中查找文件中的重复单词。
我尝试了:
egrep "(\<[a-zA-Z]+\>) \1" file.txt
和
egrep "(\b[a-zA-Z]+\b) \1" file.txt
但出于某种原因,它认为不是重复的事物却被视为重复!例如,它认为字符串“word words”符合条件,尽管有单词边界条件\>
或\b
。
我需要使用egrep(或grep -e)在Unix(bash)中查找文件中的重复单词。
我尝试了:
egrep "(\<[a-zA-Z]+\>) \1" file.txt
和
egrep "(\b[a-zA-Z]+\b) \1" file.txt
但出于某种原因,它认为不是重复的事物却被视为重复!例如,它认为字符串“word words”符合条件,尽管有单词边界条件\>
或\b
。
\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
我使用
pcregrep -M '(\b[a-zA-Z]+)\s+\1\b' *
检查我的文件是否存在这样的错误。如果在重复单词之间有换行符,也可以使用此方法。
解释:
-M, --multiline
:运行多行模式(如果在重复单词之间有换行符,则非常重要)。[a-zA-Z]+
:匹配单词。\b
:单词边界,请参阅教程。(\b[a-zA-Z]+)
:将其分组。\s+
:匹配至少一个(但尽可能多的)空格字符。这包括换行符。\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"
egrep "(\<[a-zA-Z]+>) \<\1\>" file.txt
修复了这个问题。
基本上,你需要告诉\1它也需要保持在单词边界内。
\>
和>
是不同的。(除了拼写错误之外,它与已接受的答案有何不同?)此外,请学习如何格式化代码,以便<
和>
不被解释为HTML。请参见。 - rici