Дата захвата после регулярного выражения с использованием awk - PullRequest
1 голос
/ 28 октября 2019

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

ВЫПУСК

  • Не могу понять, как передать день недели в awk. Это должно быть в формате массива? Текущий метод (tr) не заменяется на OR (||), он только дает (|), поэтому замена регулярного выражения не работает.

ПОПЫТКА SO FAR

#!/bin/bash

day_of_week=$(locale day | tr ';' '\n' | cut -c 1-3 | tr '\n' '||')

awk -v day_of_week="$day_of_week" '
/show memory compare start/,/^day_of_week/
/show memory compare end/,/^day_of_week/

' testsnmpoutput.txt

TESTFILE (testsnmpoutput.txt)

xr_lab#   show clock
Thu Sep 19 14:38:02.812 WIB
14:38:02.893 WIB Thu Sep 19 2019
xr_lab#
xr_lab#show memory compare start
Thu Sep 19 14:38:06.400 WIB
Successfully stored memory snapshot in /var/log/malloc_dump_memcmp_start.out
xr_lab#
xr_lab#
xr_lab#
xr_lab#show memory compare end
Thu Sep 19 14:40:56.123 WIB
xr_lab#show memory compare start
Thu Sep 19 14:46:28.464 WIB
Successfully stored memory snapshot in /var/log/malloc_dump_memcmp_start.out
xr_lab#
xr_lab#
xr_lab#
xr_lab#
xr_lab#show memory compare end
show memory compare report
show process memory
Thu Sep 19 14:50:10.422 WIB

Желаемый выход

xr_lab#show memory compare start
Thu Sep 19 14:38:06.400 WIB
xr_lab#show memory compare end
Thu Sep 19 14:40:56.123 WIB
xr_lab#show memory compare start
Thu Sep 19 14:46:28.464 WIB
xr_lab#show memory compare end
Thu Sep 19 14:50:10.422 WIB

Спасибо.

Ответы [ 4 ]

1 голос
/ 28 октября 2019

попробуйте это:

/show memory compare start|show memory compare end/ {
   print;
   while (getline != 0) {
      if (match($1,"Mon|Tue|Wed|Thu|Fri|Sat|Sun") != 0) {
        print;
        break;
      }
   }
}

Этот код выполняется в строках, которые содержат «начало сравнения памяти» или «конец сравнения памяти», и, начиная с этого, циклически перебирает строки, чтобы найти первую строку, котораяначинается с дня недели.

getline читает следующую запись ввода и обновляет $ 0 и NF.

1 голос
/ 28 октября 2019

Вы можете использовать

day_of_week=$(locale day | sed 's/\([^;]\{3\}\)[^;]*/\1/g');
day_of_week="${day_of_week//;/|}";
p1='show memory compare (start|end)';
awk -v pat1="$p1" -v day_of_week="$day_of_week" '($0~pat1),($0~"^("day_of_week")"){ if ($0 ~ pat1 || $0 ~ "^("day_of_week")") print $0; }' file

См. онлайн-демонстрацию .

Подробнее

  • $(locale day | sed 's/\([^;]\{3\}\)[^;]*/\1/g'); - получает список дней, разделенных ;, и сохраняет только 3 первые буквы каждого дня, удаляя оставшиеся
  • "${day_of_week//;/|}" - заменяет все ; на |
  • p1='show memory compare (start|end)' определяет переменную p1, содержащую шаблон начального диапазона (show memory compare start или show memory compare end)
  • '($0~pat1),($0~"^("day_of_week")") получает диапазон линий между начальным и конечным шаблонами (обратите внимание, что вы не можете использовать /.../ запись с регулярными выражениями, передаваемыми в качестве переменных)
  • { if ($0 ~ pat1 || $0 ~ "^("day_of_week")") print $0; } печатает только строки, соответствующие начальному или конечному шаблону.

More sed подробности команды

Команда sed 's/\([^;]\{3\}\)[^;]*/\1/g' использует шаблон POSIX BRE (так как нет параметра -E или -P), который соответствует:

  • \([^;]\{3\}\) - Группа захвата 1:
    • [^;]\{3\} - три вхождения любого символа, но ;
  • [^;]* - 0 или более символов, отличных от ;
  • \1 - матч заменен наth содержимое группы 1
  • g - все вхождения.

См. демонстрационную версию шаблона POSIX ERE (sed -E 's/([^;]{3})[^;]*/\1/g').

1 голос
/ 28 октября 2019

Не могли бы вы попробовать следующее.

awk '
BEGIN{
  num=split("mon,tue,wed,thu,fri,sat,sun",array,",")
  for(k=1;k<=num;k++){
      days[array[k]]
  }
}
/show memory compare start/{
  found_start=1
  start=$0
  next
}
found_start && tolower($1) in days{
  print start ORS $0
  found_start=start=""
}
/show memory compare end/{
  found_end=1
  end=$0
  next
}
found_end && tolower($1) in days{
  print end ORS $0
  found_end=end=""
}
'   Input_file
0 голосов
/ 29 октября 2019

Этот oneliner должен делать:

$ grep -e 'show memory compare \(start\|end\)' -e '^\(Mon\|Tue\|Wed\|Thu\|Fri\)' testsnmpoutput.txt | grep -A 1 'show memory compare' | grep -v '^--'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...