2015-10-28 4 views
1

мне нужно найти повторяющиеся слова в файле с помощью (или задать расширенное Grep -e) в UNIX (Баш)Как найти повторяющиеся слова в файле, используя grep/egrep?

Я пробовал:

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

и

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

, но по какой-то причине они считают, что вещи повторяются, а это не так! , например, он считает, что строка «словарные слова» соответствует критериям, несмотря на граничное условие слова \> или \b.

+0

Для лучшего понимания, показать некоторые входные выборки, желаемый результат, и т.д. Единственное, что мы можем сейчас сказать: «да, это работает как задумано». – fedorqui

ответ

2

\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 
1

Это ожидаемое поведение. Посмотрите, что man grep говорит:

обратной косой черты и специальные Выражения

Символы \ < и> соответственно совпадает с пустой строкой в ​​ начале и в конце слова. Символ \ b соответствует пустой строке на краю слова, а \ B соответствует пустой строке при условии, что она не на краю слова. Символ \ w является синонимом [[: alnum:]] и \ W является синонимом [^ [: alnum:]].

, а затем в другом месте мы видим, что такое "слово" является:

Matching Control

состав слова символами являются буквы, цифры и подчеркивания.

Так это то, что будет производить:

$ 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, что она должна оставаться в границах слов слишком

+0

Не работает, так как '\>' и '>' отличаются. (И как он отличается от принятого ответа, кроме опечатки?) Также, пожалуйста, научитесь форматировать код, чтобы '<' and '>' не были проиндексированы как HTML. Видеть – rici

0

Я использую

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

, чтобы проверить мои документы для таких ошибок. Это также работает, если существует разрыв строки между дублируемыми словами.

Пояснение:.

  • -M, --multiline работать в режиме многострочного (важно, если разрыв строки между дублированных словами
  • [a-zA-Z]+: Матч слова
  • \b: граница слова см tutorial
  • (\b[a-zA-Z]+) group it
  • \s+ матч по крайней мере один (но столько же, сколько nece ssary) пробельные символы. Это включает в себя новую строку.
  • \1: матч все, что было в первой группе
Смежные вопросы