Вопрос по linux, grep – Использование grep для получения следующего слова после совпадения в каждой строке

11

Я хочу получить & quot;GET& Quot; запросы из журналов моего сервера.

Например, это журнал сервера

1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:32:27] code 404, message File not fo$
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:32:27] "GET /hello HTTP/1.1" 404 -   
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57] code 404, message File not fo$
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57] "GET /ss HTTP/1.1" 404 -

Когда я пытаюсь с простым grep или awk,

Adi:~ adi$ awk '/GET/, /HTTP/' serverlogs.txt

это выдает

1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:32:27] "GET /hello HTTP/1.1" 404 -
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57] "GET /ss HTTP/1.1" 404 -

Я просто хочу отобразить:hello а такжеss

Есть ли способ сделать это?

Ваш Ответ

6   ответов
1

а не одно сложное регулярное выражение. Это работает с данными, которые вы предоставили:

fgrep GET /tmp/foo | 
    egrep -o 'GET (.*) HTTP' |
    sed -r 's/^GET \/(.+) HTTP/\1/'

Этот конвейер возвращает следующие результаты:

hello
ss

Конечно, есть и другие способы сделать работу, но она явно работает на предоставленном корпусе.

0
gawk '{match($7,/\/(\w+)/,a);} length(a[1]){print a[1]}' log.txt
hello
ss

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

12

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

grep -oP '(?<=GET\s/)\w+' file

Если у тебя нет gnu grep, я бы посоветовал просто использовать sed:

sed -n '/^.*GET[[:space:]]\{1,\}\/\([-_[:alnum:]]\{1,\}\).*$/s//\1/p' file

Если у вас есть gnu sed, это можно значительно упростить:

sed -n '/^.*GET\s\+\/\(\w\+\).*$/s//\1/p' file

Суть в том, что для этого вам, конечно, не нужны трубы.grep илиsed одного будет достаточно.

Потрясающе. Работает отлично !! Коротко и просто. aditya.gupta
6

поскольку файл журнала имеет известную структуру, одним из вариантов является использованиеcut чтобы вытащить 7-й столбец (по умолчанию поля обозначены табуляцией).

grep GET log.txt | cut -f 7 
По-прежнему показывает всю строку. 1.0.0.127.in-addr.arpa - - [10 / Июн / 2012 15:32:27] «GET / привет HTTP / 1.1» 404 - 1.0.0.127.in-addr.arpa - - [10 / Июн / 2012 15:41:57] "GET / ss HTTP / 1.1" 404 - aditya.gupta
Хммм, это пробел или табуляция? Если пробел, используйте-d' ' с надрезом для указания пробела в качестве разделителя столбцов. John Carter
Отлично работает с -d '' параметр. aditya.gupta
3

grep -o /he.* log.txt | grep -o [^/].*
grep -o /ss log.txt | grep -o [^/].*

[^ /] означает извлечь буквы после символа ^ из вывода grep

2

https: //www.unix.com/shell-programming-and-scripting/153101-print-next-word-after-found-pattern.htm

Summary: используйте grep, чтобы найти совпадающие строки, затем используйте awk, чтобы найти шаблон, и напечатайте следующее поле:

grep pattern logfile | \
  awk '{for(i=1; i<=NF; i++) if($i~/pattern/) print $(i+1)}'

Если вы хотите узнать уникальные события:

grep pattern logfile | \
  awk '{for(i=1; i<=NF; i++) if($i~/pattern/) print $(i+1)}' | \
  sort | \
  uniq -c

Похожие вопросы