Может ли GNU Grep выводить выбранную группу?


48

Можно ли использовать GNU grep для получения подходящей группы из выражения?

Пример:

echo "foo 'bar'" | grep -oE "'([^']+)'"

Который вывел бы "бар". Но я хотел бы получить просто «бар», без необходимости отправлять его через grep еще раз (т.е. получить соответствующую группу). Это возможно?

Ответы:


50

Вы можете использовать sedдля этого. На BSD sed:

echo "foo 'bar'" | sed -E "s/.*'([^']+)'.*/\\1/"

Или без -Eопции:

sed "s/.*'\([^']\+\)'.*/\1/"

Это не работает для многострочного ввода. Для этого вам нужно:

sed -n "s/.*'\([^']\+\)'.*/\1/p"

1
Хм, это на моей машине (Mac OS X). При дальнейшем рассмотрении на странице руководства: «Опции -E, -a и -i являются нестандартными расширениями FreeBSD и могут быть недоступны в других операционных системах».
jtbandes

1
Это похоже на grep'-E: «Регулярные выражения интерпретируются как расширенные (современные) регулярные выражения, а не как базовые регулярные выражения (BRE). Страница справочника re_format (7) полностью описывает оба формата».
Jtbandes

1
-R кажется, что для меня.
Торанди

1
@jtbandes: Вам не нужны расширенные функции для этого выражения. Мне просто нужны 3 экранирующих символа для ( ) +использования \( \) \+: это фактически то же самое:sed "s/.*'\([^']\+\)'.*/\1/"
Peter.O

2
Это не работает для многострочного ввода. Для этого вам нужно: sed -n "s/.*'\([^']\+\)'.*/\1/p"
подонок

28

Хотя grep не может вывести конкретную группу, вы можете использовать прогнозирование и утверждения позади, чтобы добиться того, что вы после:

echo "foo 'bar'" | grep -Po "(?<=')[^']+(?=')"


8
grep -Pдоступно не на всех платформах. Но если это так, использование lookahead / behind - очень хороший способ решения проблемы.
Себастьян

1
Является ли grep интеллектуальным с утверждениями о поиске? Как это работает с длинными оглядками? Интегрирует ли он в какое-то «дерево суффиксов» с остальной частью регулярного выражения?
Росс Роджерс

4

Вы можете использовать \Kдля сброса и отбрасывания текста совпадения левой руки вместе с предвкушением, которое не добавляется в текст совпадения:

$ echo "foo 'bar'" | grep -oP "'\K[^']+(?=')"
bar

GNU grep only.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.