Intereting Posts
Список лучших процессов одного пользователя на разных машинах? разрешение прилагаемого широкоэкранного Двойная загрузка Arch Linux и Gentoo Linux: невозможно загрузить Arch, поскольку жесткий диск не может быть найден Темы Gtk2 под Gnuo Gnome 3 Почему vim не применяет эти цветовые переменные в моей конфигурации? где или как посмотреть, переносятся ли данные по USB на массовое хранение Поведение окна сценариев в KDE зависит от используемого монитора netstat, правильно указывая соединения Разрешения Sudo группами ldap через nslcd Как найти скрытую строку в нескольких каталогах Замена столбца «время» соответствующими значениями как правильно задержать выполнение сценария запуска на основе проверенного состояния? Использование sed для обработки файла passwd Настройка Snapper / snapshots на Fedora 23 Как я могу постоянно запускать скрипт bash, проверяя, изменилось ли значение?

Несколько совпадений и печати в одной строке

Мне нужно сопоставить два шаблона в файле журнала и вам нужно получить следующую строку одного из шаблонов (из двух шаблонов), которые совпадают, и, наконец, нужно напечатать эти три значения в одной строке.

Файл пробного файла:

2013/09/05 04:26:00 Processing Batch /fbc/dev/cebi/dod/9739867262 2013/09/05 04:26:02 Batch 9739867262 was successful 2013/09/05 04:26:02 Total Time = 3.13 Secs 2013/09/05 04:26:02 Repository API Time = 2.96 Secs 2013/09/05 04:26:02 File System Io Time = 0.06 Secs 2013/09/05 04:26:02 Doc Validation Time = 0.03 Secs 2013/09/05 04:26:02 Ending @ Thu Sep 05 04:26:02 EDT 2013 2013/09/05 08:18:10 Starting @ Thu Sep 05 08:18:10 EDT 2013 2013/09/05 08:18:10 Starting @ Thu Sep 05 08:18:10 EDT 2013 2013/09/05 08:18:10 Processing Batch /fbc/dev/cebi/dod/9844867675 2013/09/05 08:18:10 Processing Batch /fbc/dev/cebi/dod/9886743777 2013/09/05 08:18:16 Batch 9844867675 was successful 2013/09/05 08:18:16 Total Time = 6.00 Secs 2013/09/05 08:18:16 Repository API Time = 5.63 Secs 2013/09/05 08:18:16 File System Io Time = 0.05 Secs 2013/09/05 08:18:16 Doc Validation Time = 0.19 Secs 2013/09/05 08:18:16 Ending @ Thu Sep 05 08:18:16 EDT 2013 2013/09/05 08:18:18 Batch 9886743777 was successful 2013/09/05 08:18:18 Total Time = 8.27 Secs 2013/09/05 08:18:18 Repository API Time = 8.52 Secs 2013/09/05 08:18:18 File System Io Time = 0.08 Secs 2013/09/05 08:18:18 Doc Validation Time = 0.47 Secs 2013/09/05 08:18:18 Ending @ Thu Sep 05 08:18:18 EDT 2013 

У меня есть номера отдельно в файле cust_no.txt

 9739867262 9844867675 9886743777 

Принимая эти цифры в качестве ввода, мне нужно сопоставить следующие два шаблона в файле журнала

  1. Обработка Batch / fbc / dev / cebi / dod /
  2. Пакет был успешным

В качестве вывода требуются следующие данные:

-> В совпадении первого шаблона ( ie Processing Batch /fbc/dev/cebi/dod/<numbers in the cust_no.txt> ) мне нужно получить второе слово, то есть $ 2. -> В совпадении вторых паттернов ( ie Batch <numbers in the cust_no.txt> was successful ) мне нужно получить второе слово, т.е. $ 2 -> И 6-е слово ($ 6) на следующей строке после матча после второго шаблон (то есть линия, смотрящая на Total Time )

Желаемый результат:

 9739867262,04:26:00,04:26:02,3.13 Secs 9844867675,08:18:10,08:18:16,6.00 Secs 9886743777,08:18:10,08:18:18,8.27 Secs 

Чтобы получить это, я попытался сделать это ниже, но это, похоже, не сработает:

 awk -v cn=$cust_no '{{if ($0 ~ "Processing.*" cn) st=$2 && if ($0 ~ "Customer cn was successful" et=$2; getline; tt=$4} ; print st,et,tt} 

Как насчет этого:

 while read number;do start=$(grep "Processing Batch /fbc/dev/cebi/dod/$number" log_file\ |head -n 1|awk '{print $2}') end=$(grep -A 1 "Batch $number was successful" log_file\ |head -n 2|tail -n 1|awk -v OFS=',' '{print $2,$6}') echo "$number,$start,$end Secs" done <cust_no.txt 

Если вы не против использования Perl & grep, это решение вашей проблемы. Вот сценарий, называемый cmd.pl :

 #!/usr/bin/env perl use feature 'say'; #use Data::Dumper; @file = `grep -f cust_no.txt -A 1 sample.log`; my (%info, $secLineSeen, $time, $custno); $secLineSeen = 0; foreach my $line (@file) { if ($secLineSeen == 1) { #2013/09/05 08:18:18 Total Time = 8.27 Secs (my $totTime) = ($line =~ m!\S+ \S+\s+Total Time\s+=\s+(\S+ Secs)!); $info{$custno}{totTime} = $totTime; $secLineSeen = 0; } elsif ($line =~ m/Processing Batch/) { #2013/09/05 08:18:10 Processing Batch /fbc/dev/cebi/dod/9844867675 ($time, $custno) = ($line =~ m!\S+ (\S+)\s+Processing Batch.*/(\S+)!); $info{$custno}{onetwo} = $time; } elsif ($line =~ m/Batch.*successful/) { #2013/09/05 08:18:18 Batch 9886743777 was successful ($time, $custno) = ($line =~ m!\S+ (\S+)\s+Batch (\S+) was.*!); $info{$custno}{twotwo} = $time; $secLineSeen = 1; } } #print Dumper(\%info); #9739867262,04:26:00,04:26:02,3.13 Secs foreach my $key (sort keys %info) { say "$key,$info{$key}{onetwo},$info{$key}{twotwo},$info{$key}{totTime}"; } 

пример

 $ ./cmd.pl 9739867262,04:26:00,04:26:02,3.13 Secs 9844867675,08:18:10,08:18:16,6.00 Secs 9886743777,08:18:10,08:18:18,8.27 Secs 

Детали

Этот скрипт Perl сначала создает массив @file , который содержит результаты этой команды:

 $ grep -f cust_no.txt -A 1 sample.log 

Эта команда принимает файл журнала, sample.log и выбирает все строки, содержащие номера клиентов, из файла cust_no.txt , например:

 2013/09/05 04:26:00 Processing Batch /fbc/dev/cebi/dod/9739867262 2013/09/05 04:26:02 Batch 9739867262 was successful 2013/09/05 04:26:02 Total Time = 3.13 Secs -- 2013/09/05 08:18:10 Processing Batch /fbc/dev/cebi/dod/9844867675 2013/09/05 08:18:10 Processing Batch /fbc/dev/cebi/dod/9886743777 2013/09/05 08:18:16 Batch 9844867675 was successful 2013/09/05 08:18:16 Total Time = 6.00 Secs -- 2013/09/05 08:18:18 Batch 9886743777 was successful 2013/09/05 08:18:18 Total Time = 8.27 Secs 

Эта команда grep делает одну дополнительную особую вещь, о которой стоит упомянуть, в основном, что она сохраняет одну дополнительную строку после ( -A 1 ) любого совпадения. Это позволяет нам захватить линию с «Общим временем» в ней.

После того, как эти данные были извлечены, скрипт Perl затем использует многомерный хеш для хранения результатов ключевых фрагментов данных из этого вывода в соответствии с вашими требованиями, упомянутыми в вопросе.

Хэш выглядит так, как только мы закончили обработку содержимого @file :

 $VAR1 = { '9739867262' => { 'twotwo' => '04:26:02', 'totTime' => '3.13 Secs', 'onetwo' => '04:26:00' }, '9886743777' => { 'twotwo' => '08:18:18', 'totTime' => '8.27 Secs', 'onetwo' => '08:18:10' }, '9844867675' => { 'twotwo' => '08:18:16', 'totTime' => '6.00 Secs', 'onetwo' => '08:18:10' } }; 

Наконец, мы перебираем этот хэш и печатаем содержимое, которое мы собрали, в формате, указанном в вопросе.

Я бы попробовал grep по этому поводу:

 grep -EA 1 'pattern1|pattern2' file.log 

Используйте опцию -E для расширенного регулярного выражения и -A для количества строк, которые следует за соответствием. Теперь, чтобы напечатать это на одной строке, я могу думать об одном очень хакерском способе, используя sed:

 grep -EA 1 'pattern1|pattern2' file.log | grep -v ^-- | sed 'N ; s+\n+|+g' 

Передача команды N (чтение следующей строки) в sed позволяет обрабатывать две строки ввода за раз. С другой стороны, команда s+\n+|+g позволяет вам заменить (с разделительным символом вашего выбора) или удалить (если подстановка пуста), новая строка между двумя обрабатываемыми строками, оставив только новую строку в конец второй линии.

grep -v ^-- мне необходимо избавиться от вывода с помощью первого экземпляра grep (см. иллюстративный пример ниже).

 Line 1 Line 2 -- Line X Line Y