Регулярное выражение для поиска двойных символов в Bash

10

Я ищу регулярное выражение, которое находит все вхождения двойных символов в тексте, листинге и т. Д. В командной строке (Bash).

Главная Вопрос : Есть ли простой способ поиска последовательностей , таких как aa, ll, tttttи т.д. , где один определяет регулярное выражение , которое выглядит для п вхождений одного и того же символа с? То, что я ищу, - это достижение этого на очень базовом уровне. В командной строке. В оболочке Linux.

После некоторых исследований я пришел к следующим ответам - и вопросам, вытекающим из них, поэтому они просто дали мне подсказку, где может быть решение. Но:

a) (e) grep и проблема обратной косой черты

  • grep 'a\{2\}' ищет aa
  • egrep'a{2}' ищет aa

Вопрос: действительно ли необходимость установки люфтов связана с командой, которую я использую? Если да, может ли кто-нибудь дать мне подсказку, что еще следует учитывать при использовании (e) grep здесь?

б) Я нашел этот ответ здесь для моего вопроса, хотя это не совсем то, что я искал:

grep -E '(.)\1' filenameищет записи с одним и тем же символом, появляющиеся более одного раза, но не спрашивает, как часто . Это близко к тому, что я ищу, но я все еще хочу установить количество повторений.

Я, вероятно, должен разделить это на два или более вопроса, но тогда я не хочу затоплять этот удивительный сайт здесь.

PS: Еще один вопрос, возможно , не по теме , но: это in, inside, atили on the shell. И on the command lineправильно ли?

erch
источник

Ответы:

8

Это действительно два вопроса, и их следовало разделить. Но так как ответы относительно просты, я помещу их здесь. Эти ответы специально для GNU grep.

а) egrepтакой же как grep -E. Оба указывают на то, что вместо grepстандартных регулярных выражений следует использовать «Расширенные регулярные выражения» . grepтребует обратной косой черты для простых регулярных выражений.

Со manстраницы:

Основные против расширенных регулярных выражений

В основных регулярных выражениях метасимволы ? , + , { , | , ( и ) теряют свое особое значение; вместо этого используйте версии с обратной косой чертой \? , \ + , \ { , \ | , \ ( и \) .

Смотрите manстраницу для дополнительной информации об исторических соглашениях и переносимости.

б) Используйте egrep '(.)\1{N}'и замените Nколичество символов, которое вы хотите заменить, минус один (так как точка соответствует первой). Поэтому, если вы хотите сопоставить символ, повторенный четыре раза, используйте egrep '(.)\1{3}'.

depquid
источник
Читая справочную страницу, я действительно неправильно понял или неправильно истолковал ту часть, на которую вы указали. Когда я работал над некоторыми учебниками по регулярным выражениям, не было никаких намеков на такое поведение. Я думал, что Regular Expression что-то означает на таком базовом уровне, что большинство приложений работают с одним и тем же набором символов. Опять я ошиблась. Спасибо за вашу помощь! Это действительно помогло мне.
erch
Также довольно странно читать « всегда используйте обратную косую черту, чтобы получить специальное значение от таких символов, как., + И т. Д. », А затем обнаруживать, что, казалось бы, обратное - это правило с самой простой командой.
erch
@ cellar.dweller Это сбивает с толку! Много рассуждений является историческим. Я более знаком с расширенной формой, поэтому у меня есть привычка всегда использовать, egrepесли мне нужны регулярные выражения (в отличие от простого сопоставления строк), чтобы мне не пришлось беспокоиться о запоминании различий между grepдвумя типы регулярных выражений.
depquid
4
Обратите внимание, что стандартные ERE не поддерживают обратные ссылки, в то время как стандартные BRE поддерживают. Так grep '\(.\)\1\{3\}'стандартно, grep -E '(.)\1{3}'нет.
Стефан Шазелас
7

Это будет искать 2 или более вхождения одного и того же персонажа:

grep -E '(.)\1+' file

Если в вашем awk есть опция -o, она будет печатать каждый матч в новой строке.

grep -Eo '(.)\1+' file

Чтобы найти совпадения точно с 3 совпадениями:

grep -E '(.)\1{2}' file

Или 3 или больше:

grep -E '(.)\1{2,}' file

и т.д..


редактировать

На самом деле @stephane_chazelas прав насчет обратных ссылок и -E. Я забыл про это. Я пробовал это в BSD grep и GNU grep, и это работает там, но это не в некоторых других greps. Вам нужно будет использовать одну из следующих версий ..

Обычные версии grep:

grep '\(.\)\1\{1,\}' file

grep -o '\(.\)\1\{1,\}' file

grep '\(.\)\1\{2\}' file

grep '\(.\)\1\{2,\}' file

-oВариант также не стандартный Grep BTW (вероятно , если ваш Grep понимает -o он может также сделать ссылку обратно) ..


Примечание : grep -E '(.)\1{2,}'файл и grep '\(.\)\1\{2\}'файл неверны, как указано alexis, и их следует игнорировать.

Scrutinizer
источник
Спасибо тебе, пока. Но: правильно ли я говорю, что без -Eвыбора grepничего не поделаешь? Это могло бы многое объяснить, например, почему я потратил столько времени на поиски ошибки.
erch
Без опции -E вы можете сделать то же самое в этом случае, но вам нужно будет избегать больше, и нет +оператора. Я также приведу примеры.
Тщательный анализ
Небольшое исправление: grep -E '(.)\1{2}'не совсем "Найти совпадения с ровно 3 совпадениями". Несмотря на то , что будет соответствовать ровно три одинаковых символов, они могут быть встроены в более неоднократного строку; например, он будет совпадать в 5-символьной строке AAAAA. (И если есть 6 или более последовательных символов, он будет совпадать более одного раза).
Алексис
Да, вы абсолютно правы, это не работает, как задумано, на самом деле это не возможно так ...
Scrutinizer
3

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

Главный вопрос был о:

Есть ли простой способ найти n случаев одного и того же персонажа, например aa,tttttt

Краткий ответ :

Следующие [варианты] команд будут повторяться aкак минимум один раз и бесконечно

grep 'a\{1,}

grep -E \(a\)\{1,\}

egrep a{1,}

или с доступными регулярными выражениями GNU grep a\+


Количество повторений задается в фигурных скобках через шаблон {min,max}{n}повторение ровно nраз, {n,}повторение как минимум nраз и {n,m}повторение как минимум, nно не чаще m.

Таким образом, как следствие, возникла вторичная проблема :

Связана ли необходимость установки зазоров с командой, которую я использую?

Короткий ответ : Да, использование обратной косой черты зависит от того , одного использования grepилиegrep

  • grep: обратная косая черта активирует метасимволы [использует основные регулярные выражения]
  • egrepобратный слэш де -activates метасимволы [использует расширенные регулярные выражения]

Поскольку это краткий ответ, я хочу предоставить тем, кто сталкивался с сопоставимыми проблемами, я добавил свое основное резюме того, о чем, по-видимому, нужно знать, работая с grepи egrep.




Регулярные выражения Basic, Extended и GNU

Основные регулярные выражения

Используется в grep, edи sedкоманда

Основные функции набора регулярных выражений:

  • Большинство метасимволов, например, ? [ . \ )и т. Д. Активируются через обратную косую черту. Если обратной косой черты нет, они будут восприняты как (часть) поискового запроса.
  • ^ $ \<и \>поддерживаются без обратной косой черты
  • Нет сокращенных символов [ \b, \sи т. Д.]

Основные регулярные выражения GNU добавляют к этим

  • \?Повторите символ ноль или один раз ( c\?соответствует cи cc) и является альтернативой для\{0,1\}
  • \+повторить символ хотя бы один раз ( c\+совпадения ccи ccccccccт. д.) и является альтернативой\{1,\}

  • \|поддерживается (например, grep a\|bбудет искать aилиb

grep -E позволяет команде использовать весь набор расширенных регулярных выражений:


Расширенные регулярные выражения [ERE]

Используется в egrep, awkи emacsявляется основной набор плюс довольно некоторые особенности.

  • Метасимволы деактивируются через обратную косую черту
  • Обратных ссылок нет
  • еще: много волшебных регулярных выражений обычно можно сделать для одного

GNU Extendend Регулярные выражения

добавляет следующие функции

Две ссылки будут направлять одну на регулярные-экспресс-сайты.инфо, которые, в дополнение к потрясающей поддержке, которую я получил, действительно очень мне помогли.

erch
источник