Grep Сопоставить и извлечь

Grep Сопоставить и извлечь

У меня есть файл, который содержит строки, как

proto=tcp/http  sent=144        rcvd=52 spkt=3 
proto=tcp/https  sent=145        rcvd=52 spkt=3
proto=udp/dns  sent=144        rcvd=52 spkt=3

Мне нужно извлечь значение proto, которое равно tcp/http, tcp/https, udp/dns.

До сих пор я пробовал это сделать, grep -o 'proto=[^/]*/'но смог извлечь значение только в виде proto=tcp/.

решение1

С grep -o, вам придется сопоставлять именно то, что вы хотите извлечь. Поскольку вы не хотите извлекать строку proto=, вам не следует сопоставлять ее.

Расширенное регулярное выражение, которое будет соответствовать либо tcp, либо , udpза которым следует косая черта и некоторая непустая буквенно-цифровая строка:

(tcp|udp)/[[:alnum:]]+

Применяем это к вашим данным:

$ grep -E -o '(tcp|udp)/[[:alnum:]]+' file
tcp/http
tcp/https
udp/dns

Чтобы убедиться, что мы делаем это только для строк, начинающихся со строки proto=:

grep '^proto=' file | grep -E -o '(tcp|udp)/[[:alnum:]]+'

С помощью sed, удалив все до первого =и после первого пробела:

$ sed 's/^[^=]*=//; s/[[:blank:]].*//' file
tcp/http
tcp/https
udp/dns

Чтобы убедиться, что мы делаем это только для строк, начинающихся со строки proto=, вы можете вставить тот же шаг предварительной обработки, что grepи выше, или вы можете использовать

sed -n '/^proto=/{ s/^[^=]*=//; s/[[:blank:]].*//; p; }' file

Здесь мы подавляем вывод по умолчанию с помощью -nпараметра, а затем запускаем подстановки и явную печать строки только в том случае, если строка соответствует ^proto=.


С помощью awk, используя разделитель полей по умолчанию, а затем разделив первое поле =и выведя его вторую часть:

$ awk '{ split($1, a, "="); print a[2] }' file
tcp/http
tcp/https
udp/dns

Чтобы убедиться, что мы делаем это только для строк, начинающихся со строки proto=, вы можете вставить тот же шаг предварительной обработки, что grepи выше, или вы можете использовать

awk '/^proto=/ { split($1, a, "="); print a[2] }' file

решение2

Если вы используете GNU grep (для -Pопции), вы можете использовать:

$ grep -oP 'proto=\K[^ ]*' file
tcp/http
tcp/https
udp/dns

Здесь мы сопоставляем proto=строку, чтобы убедиться, что извлекаем правильный столбец, но затем отбрасываем его из вывода с помощью флага \K.

Вышеуказанное предполагает, что столбцы разделены пробелами. Если табуляция также является допустимым разделителем, вы должны использовать \Sдля сопоставления непробельных символов, поэтому команда будет выглядеть так:

grep -oP 'proto=\K\S*' file

Если вы также хотите защитить поля совпадений, где proto=есть подстрока, например thisisnotaproto=tcp/https, , вы можете добавить границу слова \bследующим образом:

grep -oP '\bproto=\K\S*' file

решение3

С использованием awk:

awk '$1 ~ "proto" { sub(/proto=/, ""); print $1 }' input

$1 ~ "proto"гарантирует, что мы предпримем действия только по строкам protoв первом столбце

sub(/proto=/, "")удалит proto=из ввода

print $1печатает оставшийся столбец


$ awk '$1 ~ "proto" { sub(/proto=/, ""); print $1 }' input
tcp/http
tcp/https
udp/dns

решение4

Еще одно grepрешение:

grep -o '[^=/]\+/[^ ]\+' file

И аналогичный пример с sedвыводом только совпавшей захваченной группы:

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

Связанный контент