Можно ли использовать GNU grep для получения подходящей группы из выражения?
Пример:
echo "foo 'bar'" | grep -oE "'([^']+)'"
Который вывел бы "бар". Но я хотел бы получить просто «бар», без необходимости отправлять его через grep еще раз (то есть получить соответствующую группу). Это возможно?
3 ответа на вопрос
47
jtbandes
Вы можете использовать sedдля этого. На BSD sed:
echo "foo 'bar'" | sed -E "s/.*'([^']+)'.*/\\1/"
Или без -Eопции:
sed "s/.*'\([^']\+\)'.*/\1/"
Это не работает для многострочного ввода. Для этого вам нужно:
sed -n "s/.*'\([^']\+\)'.*/\1/p"
Спасибо, забыл о седе. Но чтобы уточнить, sed не принимает аргумент -E ..
Torandi 15 лет назад
0
Хм, это на моей машине (Mac OS X). После дальнейшего изучения, на странице руководства: «Опции -E, -a и -i являются нестандартными расширениями FreeBSD и могут быть недоступны в других операционных системах».
jtbandes 15 лет назад
0
Хорошо, это не относится к моему (debian), что должен делать -E?
Torandi 15 лет назад
0
Это похоже на 'grep` -E: «Регулярные выражения интерпретируются как расширенные (современные) регулярные выражения, а не как базовые регулярные выражения (BRE). Страница справочника re_format (7) полностью описывает оба формата».
jtbandes 15 лет назад
0
-R кажется, что для меня.
Torandi 15 лет назад
1
И у меня нет -r. Ну что ж!
jtbandes 15 лет назад
0
@jtbandes: Вам не нужны расширенные возможности для этого выражения. Мне просто нужно 3 управляющих символа для `() +` use `\ (\) \ +`: это фактически то же самое: `sed" s /. * '\ ([^] \ + \). * / \ 1 / "`
Peter.O 12 лет назад
1
Это не работает для многострочного ввода. Для этого вам нужно: `sed -n" s /.* '\ ([^'] \ + \) '. * / \ 1 / p "`
phreakhead 12 лет назад
2
26
Aldrik
Хотя grep не может выводить определенную группу, вы можете использовать прогнозирование и утверждения позади, чтобы добиться того, что вы после:
echo "foo 'bar'" | grep -Po "(?<=')[^']+(?=')"
`grep -P` доступен не на всех платформах. Но если это так, использование lookahead / behind - очень хороший способ решения проблемы.
Sébastien 12 лет назад
6
Действительно ли grep интеллектуален с утверждениями о заглядывании? Как это работает с длинными оглядками? Интегрирует ли он в какое-то [[суффиксное дерево]] (http://en.wikipedia.org/wiki/Suffix_tree) с остальной частью регулярного выражения?
Ross Rogers 12 лет назад
1
2
drewk
Вы можете использовать \Kдля сброса и отбрасывания текста совпадения левой руки вместе с предвкушением, которое не добавляется в текст совпадения: