AWK: доступ к захваченной группе по шаблону линии - PullRequest
202 голосов
/ 02 июня 2010

Если у меня есть команда awk

pattern { ... }

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

Ответы [ 6 ]

292 голосов
/ 12 января 2011

С gawk вы можете использовать функцию match для захвата заключенных в скобки групп.

gawk 'match($0, pattern, ary) {print ary[1]}' 

пример:

echo "abcdef" | gawk 'match($0, /b(.*)e/, a) {print a[1]}' 

выходы cd.

Обратите внимание на конкретное использование gawk, которое реализует данную функцию.

Для портативной альтернативы вы можете достичь аналогичных результатов с match() и substr.

пример:

echo "abcdef" | awk 'match($0, /b[^e]*/) {print substr($0, RSTART+1, RLENGTH-1)}'

выходы cd.

147 голосов
/ 02 июня 2010

Это была прогулка по переулку памяти ...

Я давно заменил awk на perl.

Очевидно, что механизм регулярных выражений AWK не захватывает его группы.

вы могли бы рассмотреть возможность использования что-то вроде:

perl -n -e'/test(\d+)/ && print $1'

флаг -n заставляет perl зацикливаться на каждой строке, как это делает awk.

27 голосов
/ 30 декабря 2012

Это то, что мне нужно постоянно, поэтому я создал для него функцию bash. Он основан на ответе Гленна Джекмана.

Определение

Добавьте это в свой .bash_profile и т. Д.

function regex { gawk 'match($0,/'$1'/, ary) {print ary['${2:-'0'}']}'; }

Использование

Захват регулярных выражений для каждой строки в файле

$ cat filename | regex '.*'

Захват 1-й группы захвата регулярных выражений для каждой строки в файле

$ cat filename | regex '(.*)' 1
12 голосов
/ 28 ноября 2012

Вы можете использовать GNU awk:

$ cat hta
RewriteCond %{HTTP_HOST} !^www\.mysite\.net$
RewriteRule (.*) http://www.mysite.net/$1 [R=301,L]

$ gawk 'match($0, /.*(http.*?)\$/, m) { print m[1]; }' < hta
http://www.mysite.net/
3 голосов
/ 21 марта 2012

Вы также можете смоделировать захват в vanilla awk без расширений. Это не интуитивно, хотя:

шаг 1. используйте gensub для окружения совпадений каким-либо символом, который не появляется в вашей строке. Шаг 2. Используйте раскол против персонажа. Шаг 3. Каждый другой элемент в расщепленном массиве является вашей группой захвата.

$ echo 'ab cb ad' | awk '{ split(gensub(/a./,SUBSEP"&"SUBSEP,"g",$0),cap,SUBSEP); print cap[2]"|" cap[4] ; }'
ab|ad
0 голосов
/ 03 августа 2016

Я немного изо всех сил пытался придумать функцию bash, которая заключает в себе ответ Питера Тиллемана, но вот что я придумал:

функция регулярного выражения { perl -n -e "/ $ 1 / && printf \"% s \ n \ "," '$ 1' }

Я обнаружил, что это работает лучше, чем основанная на awk функция opsb для следующего аргумента регулярного выражения, потому что я не хочу выводить "ms".

'([0-9]*)ms$'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...