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


10

Я шукаю регулярний вираз, який знаходить усі випадки подвійних символів у тексті, списку тощо у командному рядку (Bash).

Головне запитання : Чи є простий спосіб шукати такі послідовності, як aa, llі tttttт. Д., Де можна визначити регулярний вираз, який шукає n випадків того самого символу? Що я шукаю, це досягти цього на дуже-дуже базовому рівні. У командному рядку. У оболонці Linux.

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

a) (e) греп та проблема зворотної косої риски

  • 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правильно?

Відповіді:


8

Це справді два питання, і їх слід було розділити. Але оскільки відповіді відносно прості, я їх викладу сюди. Ці відповіді спеціально для GNU grep.

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

Зі manсторінки:

Основні та розширені регулярні вирази

У основних регулярних виразах мета-символи ? , + , { , | , ( і ) втрачають своє особливе значення; замість цього використовувати зворотні косові версії \? , \ + , \ { , \ | , \ ( і \) .

Див. manСторінку для отримання додаткових відомостей про історичні звичаї та переносимість.

b) Використовуйте egrep '(.)\1{N}'та замініть Nкількість символів, які ви хочете замінити мінус один (оскільки крапка відповідає першій). Тож якщо ви хочете відповідати персонажу, повторюваному чотири рази, використовуйте egrep '(.)\1{3}'.


Під час читання чоловічої сторінки я, мабуть, дійсно неправильно зрозумів або неправильно зрозумів ту частину, на яку ти вказав. Коли я працював над деякими навчальними посібниками з регулярного висловлення, не було жодних натяків на таку поведінку. Я подумав, що Regular Expression означає щось на такому базовому рівні, що більшість програм працює з тим самим набором символів. Знову ж таки, я був доведений неправильним. Спасибі за вашу допомогу! Це мені справді допомогло.
ерч

Це також досить заплутане читання " завжди використовуйте звороту косу рису, щоб взяти спеціальне значення у таких символів, як .
erch

@ cellar.dweller Це заплутано! Багато міркувань історичні. Я більше знайомий з розширеною формою, тому я звик завжди просто використовувати, egrepякщо мені потрібні регулярні вирази (на відміну від простого узгодження рядків), так що мені не потрібно турбуватися про запам'ятовування відмінностей між grepдвома типи регулярних виразів.
декап

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, і він працює там, але він не є в інших грепах. Вам потрібно буде скористатися однією з наведених нижче версій.

Регулярні греп-версії:

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

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

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

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

Цей -oваріант також не є стандартним грепом BTW (можливо, якщо ваш греп розуміє - він також може зробити зворотній посилання) ..


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


Дякую, поки що. Але: Я правильно кажу, що без цього -Eваріанту grepне обійшлося б багато? Це пояснило б досить багато, наприклад, чому я витратив стільки часу на пошуки того, де помилявся!
erch

Без опції -E ви можете зробити те саме в цьому випадку, але вам потрібно буде бігти більше, і немає +оператора .. Я також розміщую приклади.
Scrutinizer

Невелика корекція: grep -E '(.)\1{2}'не відповідає "Знайти матчі точно з 3-ма сірниками". Хоча це відповідатиме рівно трьом однаковим символам, вони можуть бути вбудовані у довший повторний рядок; наприклад, він буде відповідати в 5-символьному рядку AAAAA. (І якщо є 6 або більше послідовних символів, вони збігатимуться не один раз).
alexis

Так, ви абсолютно праві, що не працює так, як задумано, насправді це неможливо так.
Scrutinizer

3

По-перше, дякую всім за підтримку коментарів та пропозицій. Як виявляється, я вже був досить близький до відповіді.

Головне питання був про:

Чи є простий спосіб шукати російські випадки того самого характеру, наприклад 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: зворотна косою рискою активує метахарактери [використовує основні регулярні вирази]
  • egrepbackslash de- активує метахарактери [використовує розширені регулярні вирази]

Оскільки це коротка відповідь, я хочу надати тим, хто зіткнувся з подібними питаннями, я додав своє основне резюме того, що з них, здавалося б, слід знати, працювати з grepі egrep.




Основні, розширені та регулярні вирази 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

додає такі функції

Два посилання направлять одне на regular-expressions.info, що, крім чудової підтримки, яку я тут отримав, дуже допомогло мені.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.