використання чергування "|" у виразці sed


78

Я використовую sed, GNU sed версії 4.2.1. Я хочу використовувати чергування "|" символ у піддекспресії. Наприклад :

echo "blia blib bou blf" | sed 's/bl\(ia|f\)//g'

повинен повернутися

" blib bou "

але воно повертається

"blia blib bou blf".

Як я можу отримати очікуваний результат?

Відповіді:


110

Значок "|" також потрібен зворотний нахил, щоб отримати його особливе значення.

echo "blia blib bou blf" | sed 's/bl\(ia\|f\)//g'

зробить те, що ти хочеш.

Як відомо, якщо все інше не вдасться, прочитайте посібник :-).

Посібник користувача GNU sed , розділ 3.3 Огляд синтаксису регулярних виразів :

`REGEXP1 \ | REGEXP2 '

Відповідає або REGEXP1, або REGEXP2.

Зверніть увагу на зворотний нахил ...

На жаль, синтаксис регулярних виразів насправді не стандартизований ... Є багато варіантів, які відрізняються між іншим, у яких "особливі символи" потребують \, а які ні. У деяких це навіть налаштовується або залежить від перемикачів (як у GNU grep, яким ви можете перемикатися між трьома різними діалектами регулярних виразів).

Зокрема, ця відповідь стосується GNU sed . Є й інші sedваріанти, наприклад, той, який використовується в BSD, які ведуть себе по-різному.


35
Для всіх, хто бентежить ця відповідь \ | працює лише в gnu sed (gsed on os x), а не vanilla sed (sed on os x).
Ендрю Ханкокс

@AndrewHancox Дякую вам велике! Я збирався зірвати все волосся з голови (і поки що я роблю досить непогано в порівнянні з моїм менеджером на передній частині волосся) - я знаю, що знаю RegEx достатньо, щоб спробувати | та \ | але я ніколи не замислювався над тим, що OSX може насправді використовувати не-gnu sed.
phatskat

8
Стандартна версія BSD / OS X sedпідтримує чергування, але лише з "розширеним" синтаксисом регулярного виразів ( -E) - що означає відсутність зворотних косих рисоків ні в трубах, ні в дужках:echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
Позначити Reed

2
Я відредагував свою відповідь, щоб зазначити, що це лише для GNU sed.
sleske

22

Оскільки існує декілька коментарів щодо не-Gnu- sedреалізацій: Принаймні в OS X, ви можете використовувати -Eаргумент для  sed:

Інтерпретувати регулярні вирази як розширені (сучасні) регулярні вирази, а не основні регулярні вирази (BRE). Сторінка керівництва re_format (7) повністю описує обидва формати.

Тоді ви можете використовувати метахарактеристики регулярних виразів, не уникаючи їх. Приклад:

$ echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
 blib bou 

12

GNU sed також підтримує -rопцію (розширені регулярні вирази). Це означає, що вам не доведеться уникати метахарактерів:

echo foohello barhello | sed -re "s/(foo|bar)hello/hi/g"

Вихід:

hi hi

Так, -rваріант дійсно дуже корисний для читабельності виразів. Це повинна бути прийнята відповідь.
рüффп

9

\|Чи не працює з СЕД на Solaris 10 або. Що я зробив, було корисно

perl -p -e 's/bl(ia|f)//g'

2
+1 для портативності, оскільки якщо система має perl, вона завжди використовуватиме цей синтаксис, на відміну від sed.
зол

4

Подальше: sed -E дозволяє це на MacOS. Не потрібно зворотної косої риси для |.

 sed -E 's/this|orthat/oooo/g' infile

1

У GnuWin32 в Windows sed синтаксис є sed "s/thing1\|thing2/ /g" source > destination.

Лапки повинні "бути типовими - це "Потрібно" для розбору команди.

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