Как напечатать шаблон регулярного выражения с помощью awk? - PullRequest
86 голосов
/ 04 апреля 2011

Используя awk, мне нужно найти слово в файле, которое соответствует шаблону регулярных выражений.

Я только хочу напечатать слово, соответствующее шаблону.

Так что если в строке, у меня есть:

xxx yyy zzz

И рисунок:

/yyy/

Я хочу получить только:

yyy

EDIT: благодаря куруми мне удалось написать что-то вроде этого:

awk '{
        for(i=1; i<=NF; i++) {
                tmp=match($i, /[0-9]..?.?[^A-Za-z0-9]/)
                if(tmp) {
                        print $i
                }
        }
}' $1

и это то, что мне было нужно :) большое спасибо!

Ответы [ 6 ]

128 голосов
/ 04 апреля 2011

Это самый простой

awk '/pattern/{ print $0 }' file

попросите awk найти pattern, используя //, затем распечатайте строку, которая по умолчанию называется записью, обозначенной $ 0. По крайней мере, прочитайте документацию .

Если вы хотите только распечатать соответствующее слово.

awk '{for(i=1;i<=NF;i++){ if($i=="yyy"){print $i} } }' file
95 голосов
/ 04 апреля 2011

Похоже, вы пытаетесь эмулировать поведение GNU grep -o. Это будет сделано при условии, что вы захотите только первое совпадение в каждой строке:

awk 'match($0, /regex/) {
    print substr($0, RSTART, RLENGTH)
}
' file

Вот пример:

% awk 'match($0, /a.t/) {
    print substr($0, RSTART, RLENGTH)
}
' /usr/share/dict/words | head
act
act
act
act
aft
ant
apt
art
art
art

Читайте о match, substr, RSTART и RLENGTH в руководстве awk .

После этого вы можете расширить это, чтобы иметь дело с несколькими совпадениями на одной линии. Я не могу сделать все домашнее задание для вас: -)

28 голосов
/ 04 июня 2015

gawk может получить соответствующую часть каждой строки, используя это как действие:

{ if (match($0,/your regexp/,m)) print m[0] }

match (строка, регулярное выражение [, массив]) Если массив присутствует, он очищается, а затем нулевой элемент массива устанавливается на всю часть строка соответствует регулярному выражению Если регулярное выражение содержит круглые скобки, Индексированные по целому элементу элементы массива должны содержать часть строка, соответствующая заключенному в скобки подвыражению. http://www.gnu.org/software/gawk/manual/gawk.html#String-Functions

10 голосов
/ 10 сентября 2015

Если Perl является опцией, вы можете попробовать это:

perl -lne 'print $1 if /(regex)/' file

Чтобы реализовать сопоставление без учета регистра, добавьте модификатор i

perl -lne 'print $1 if /(regex)/i' file

Чтобы напечатать все ПОСЛЕmatch:

perl -lne 'if ($found){print} else{if (/regex(.*)/){print $1; $found++}}' textfile

Чтобы напечатать матч и все, что будет после матча:

perl -lne 'if ($found){print} else{if (/(regex.*)/){print $1; $found++}}' textfile
9 голосов
/ 13 марта 2014

Если вас интересует только последняя строка ввода и вы ожидаете найти только одно совпадение (например, часть итоговой строки команды оболочки), вы также можете попробовать этот очень компактный код, принятый из Как напечатать соответствия регулярному выражению с помощью `awk`? :

$ echo "xxx yyy zzz" | awk '{match($0,"yyy",a)}END{print a[0]}'
yyy

Или более сложная версия с частичным результатом:

$ echo "xxx=a yyy=b zzz=c" | awk '{match($0,"yyy=([^ ]+)",a)}END{print a[1]}'
b

Предупреждение: awk *Функция 1010 * с тремя аргументами существует только в gawk, а не в mawk

Вот еще одно приятное решение, использующее регулярное выражение lookbehind в grep вместо awk.Это решение предъявляет более низкие требования к вашей установке:

$ echo "xxx=a yyy=b zzz=c" | grep -Po '(?<=yyy=)[^ ]+'
b
2 голосов
/ 05 июля 2018

Использование sed также может быть элегантным в этой ситуации.Пример (заменить строку на соответствующую группу "ггг" из строки):

$ cat testfile
xxx yyy zzz
yyy xxx zzz
$ cat testfile | sed -r 's#^.*(yyy).*$#\1#g'
yyy
yyy

Соответствующая страница справочника: https://www.gnu.org/software/sed/manual/sed.html#Back_002dreferences-and-Subexpressions

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...