Получить определенную информацию из файла журнала

Я хочу получить некоторые части из моего файла журнала, я попытался разрезать часть запроса, чтобы получить пользователя, модуль, действие, doAjax и ajaxAction

Например, у меня есть

195.xx.xx - - [25/Apr/2017:09:60:xx +0200] "POST /userx/index.php?m=contacts&a=form&... 192.xx.xx - - [25/Apr/2017:09:45:xx +0200] "POST /usery/index.php?m=customer&doajax=request&action=getContacts... 197.xx.xx - - [25/Apr/2017:09:20:xx +0200] "GET /userx/index.php?m=meeting&doajax=date&id=3 

и я хочу иметь:

 [user]|[module]|[action]|[doAjax]|[ajaxAction] usery contacts form null null userx customer null request getContacts userz meeting null date null 

Где:

 userx --> user m=xxx -->module a=xxx -->action doajax=xxx-->doAjax action=xxx-->ajaxAction 

Я попытался использовать awk , но только для 7-го столбца, где я могу найти свой запрос с помощью этой команды:

 awk '{printf $7; next ; }' logfile 

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

  • Sed заменить не функционирует, как ожидалось
  • Удалите обе строки, если значения столбца A повторяются в следующей строке
  • Введите количество совпадений и количество строк совпадения
  • Использование sed для поиска и замены сложной строки (желательно с регулярным выражением)
  • Сопоставьте начало линии с чем-то там?
  • Извлечь определенное значение из блоков данных
  • Отображение файла в другом файле
  • sed или awk: удалить строку, которая начинается с числа и заканчивается на rpm
  • 3 Solutions collect form web for “Получить определенную информацию из файла журнала”

    Перл «однострочный»:

     $ perl -lne ' BEGIN{ printf "%-10s%-10s%-10s%-10s%-15s\n", qw([user] [module] [action] [doAjax] [ajaxAction]); } $usr = $mde = $act = $doAj = $ajAc = "null"; $usr=$1 if m|\s/([^/]+)/|; $mde=$1 if /m=(.+?)(&|$)/; $act=$1 if /a=(.+?)(&|$)/; $doAj=$1 if /doajax=(.+?)(&|$)/; $ajAc=$1 if /action=(.+?)(&|$)/; printf "%-10s%-10s%-10s%-10s%-15s\n", ($usr,$mde,$act,$doAj,$ajAc)' file [user] [module] [action] [doAjax] [ajaxAction] userx contacts form null null usery customer null request getContacts userx meeting null date null 

    Основной трюк здесь состоит в том, чтобы искать каждую строку, идентифицирующую ваши части URL, и, если она найдена, установите для нее соответствующую переменную. В каждом случае мы ищем идентификатор, за которым следует a = (например, m= ), а затем либо a, либо конец строки (&|$) . Поскольку согласованная часть помещается в скобки (например, m=(.+?) ), Мы можем тогда ссылаться на нее как на $2 и это то, что сохраняется в каждой переменной.

    Если вам действительно нужно иметь | как разделитель, и не возражаете против того, что он сделает вывод менее читаемым, вы можете использовать его вместо этого:

     $ perl -lne ' BEGIN{ printf "%s|%s|%s|%s|%s\n", qw([user] [module] [action] [doAjax] [ajaxAction]); } $usr = $mde = $act = $doAj = $ajAc = "null"; $usr=$1 if m|\s/([^/]+)/|; $mde=$1 if /m=(.+?)(&|$)/; $act=$1 if /a=(.+?)(&|$)/; $doAj=$1 if /doajax=(.+?)(&|$)/; $ajAc=$1 if /action=(.+?)(&|$)/; print join "|", ($usr,$mde,$act,$doAj,$ajAc)' file [user]|[module]|[action]|[doAjax]|[ajaxAction] userx|contacts|form|null|null usery|customer|null|request|getContacts userx|meeting|null|date|null 

    Лучшим (более читаемым выходом) будет использование printf :

    Если вы предпочитаете делать это в awk, вы можете сделать следующее. Split позволяет разделить строку с любым разделителем полей.

     awk '{split($7,a,"/"); split(a[3],b,"m="); split(b[2],c,"&"); split(c[2],d,"="); print a[2], c[1], d[1], d[2] }' logfile 

    Это создает нужные столбцы.

     userx contacts a form usery customer doajax request userx meeting doajax date 

    Остальным шагом является форматирование. Массивы в awk являются ассоциативными и могут быть проиндексированы со строками – см. Здесь . Вы можете сделать следующее: здесь op (short для вывода) инициализируется нулем. Затем положим op[d[1]]=d[2] .

     awk '{split($7,a,"/"); split(a[3],b,"m="); split(b[2],c,"&"); split(c[2],d,"="); op["a"]="null"; op["doajax"]="null"; op["ajaxaction"]="null"; op[d[1]]=d[2];print a[2], c[1], op["a"], op["doajax"], op["ajaxaction"] }' junk.txt 

    [изменено на]

     awk '{split($7,a,"/"); split(a[3],b,"m="); split(b[2],c,"&"); split(c[2],d,"="); op["a"]="null"; op["doajax"]="null"; op["action"]="null"; op[d[1]]=d[2]; split(c[3],f,"="); split(f[2],g,"."); op[f[1]]=g[1]; print a[2], c[1], op["a"], op["doajax"], op["action"] }' junk.txt 

    Вывод выглядит следующим образом

     userx contacts form null null usery customer null request getContacts userx meeting null date null 
     perl -lane ' BEGIN { print $H = join "|", map { s/.*/[$&]/r } @H = qw/user module action doAjax ajaxAction/; pos($H) = 0; push(@pos, pos($H)-$p), $p=pos($H) while $H =~ /\[/g; $fmt = join "", map { "\%-${_}s" } @pos[1..$#pos], length($H)-$p; } my(%h, %H) = $F[-1] =~ /[?&]\K([^=]+)=([^&]+)/g; @H{@H} = ($F[-1] =~ m|^/([^/]+)|, @h{qw/ma doajax action/}); print sprintf $fmt, map { $H{$_} // "null" } @H; ' logfile 

    Результаты

     [user]|[module]|[action]|[doAjax]|[ajaxAction] userx contacts form null null usery customer null request getContacts userx meeting null date null 

    объяснение

    1. Параметры Perl:

      -l делает ORS = RS = \n

      -a хранит поля в массиве @F полученные путем разбиения текущей записи на /\s+/ , поэтому, например, $F[0] => $1, $F[1] => $2, ..., $F[-1] => $NF

      -n устанавливает неявный цикл, который считывает входной файл по строкам и без вывода, если только не запрашивается.

    2. Блок BEGIN:

      Сначала мы печатаем заголовок. Затем мы определяем формат динамически на основе заголовка. Для каждой прочитанной строки мы устанавливаем хэш% h, чьи ключи являются строками before =, а значения – строка after =. Строка, на которую нужно смотреть, примыкает? или & слева и & справа. Затем мы установили еще один хэш% H, ключи которого переименованы в версии хэша% h. Затем мы печатаем хэш на основе формата, который мы вычислили в блоке BEGIN.

    Linux и Unix - лучшая ОС в мире.