我需要在 unix(bash)中使用 egrep(或 grep -e)在文件中查找重复的单词
我试过了:
egrep "(\<[a-zA-Z]+\>) \1" file.txt
和
egrep "(\b[a-zA-Z]+\b) \1" file.txt
但由于某种原因,这些认为事情不是重复的!例如,它认为字符串“word words”符合条件,尽管存在单词边界条件\>
or \b
。
我需要在 unix(bash)中使用 egrep(或 grep -e)在文件中查找重复的单词
我试过了:
egrep "(\<[a-zA-Z]+\>) \1" file.txt
和
egrep "(\b[a-zA-Z]+\b) \1" file.txt
但由于某种原因,这些认为事情不是重复的!例如,它认为字符串“word words”符合条件,尽管存在单词边界条件\>
or \b
。
\1
匹配第一次捕获匹配的任何字符串。这与匹配与第一次捕获匹配的相同模式不同。因此,在单词边界上匹配的第一个捕获不再相关,即使\b
在捕获括号内。
如果您希望第二个实例也位于单词边界上,则需要这样说:
egrep "(\b[a-zA-Z]+) \1\b" file.txt
这与:
egrep "\b([a-zA-Z]+) \1\b" file.txt
模式中的空格强制使用单词边界,因此我删除了多余\b
的 s。如果您想更明确,可以将它们放入:
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:]] 的同义词。
然后在另一个地方我们看到“单词”是什么:
匹配控制
构成单词的字符是字母、数字和下划线。
所以这将产生:
$ 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 它也需要保持在单词边界内