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

Самый простой путь с find :

find / -daystart -mtime +41 -mtime -408 \
  -printf "%M %n %u %g %10s %TY-%Tm-%Td %Ta %TH:%TM:%TS %h/%f\n" |
awk '($7=="Fri"){print}'

Корректируйтесь -printf как требуется я заставил его посмотреть близко к ls -l здесь. %T%A %C) позвольте Вам использовать strftime() форматирование для меток времени, %Ta будучи днем недели. (Вы, возможно, должны скорректировать дневные диапазоны 41 - 408, но это - действительно просто оптимизация, Вы можете просто grep 2012, или корректируйтесь -printf помочь grep.)

Править: более устойчивая версия, с некоторой небольшой потерей ясности:

find / -daystart -mtime +41 -mtime -408 \
   -printf "%M %n %u %g %10s %TY-%Tm-%Td %Ta %TH:%TM:%TS\0%h/%f\0\0" |
gawk 'BEGIN{RS="\0\0"; FS="[\0]"} ($1~/ Fri /) { printf $2 "\0"}' | 
xargs -0 -n 1 -i ls -l "{}"

Это эмулирует -print0, но каждая строка имеет два \0 разграниченные поля, при этом имя файла является вторым. Замена ls -l "{}" в конце с тем, что необходимо сделать в файл (файлы). Я явно использую gawk, другие awks не берут настолько любезно к \0 байтам в RS/FS (обновленный для обработки новых строк в именах файлов также).

Кроме того, как предложено mreithub можно использовать %Tu а также, или вместо %Ta в течение пронумерованного рабочего дня, независимой от языка опции.

8
26.06.2014, 21:21
2 ответа

Очень простой подход будет

awk '{print > NR".entry"}END{print NR" entries"}' RS="]]" file 

Это позволит создать отдельный файл для каждой записи и распечатать количество записей, найденных в стандартном выводе.

Объяснение

  • NR - это текущий номер строки в awk.
  • RS="]]" устанавливает разделитель записей (что определяет "строку") на ]. Это означает, что каждая запись будет рассматриваться как одна строка с помощью awk.
  • {печать > NR".entry"} : это печатает текущую строку (запись) в файл с именем [Номер строки].entry. Таким образом, 1.entry будет содержать 1-ю, 2.entry вторую и так далее.
  • END{print NR" entries"} : END блок выполняется после обработки всего входного файла. Поэтому в этот момент NR будет количество обработанных записей.

Можно сохранить это как псевдоним или сделать так:

#!/usr/bin/env bash
awk '{print > NR".entry"}END{print NR" entries"}' RS="]]" "$1"

Затем запустить скрипт (предполагая, что он называется foo.sh и находится в вашем $PATH) с целевым файлом в качестве аргумента:

foo.sh file

Можно также подкорректировать имена выходных файлов. Например, чтобы файлы назывались [дата].[номер записи].[запись] вместо этого используйте следующее:

#!/usr/bin/env bash
date=$(date +%Y%m%d)
awk '{print > d"."NR".entry"}END{print NR" entries"}' RS="]]" d="$date" "$1"

Вышеизложенное предполагает, что Ваш лог-файл состоит исключительно из записей "Событие". Если это не так, и у вас могут быть другие строки, и эти строки должны быть проигнорированы, используйте вместо этого:

 #!/usr/bin/env bash
date=$(date +%Y%m%d)
awk '{
        if(/\[\[/){a=1; c++;}
        if(/\]\]/){a=0; print > d"."c".entry"}
        if(a==1){print >> d"."c".entry"}
}' d="$date" file 

Или, как один лайнер:

awk '{if(/\[\[/){a=1; c++;}if(/\]\]/){a=0; print > d"."c".entry"}if(a==1){print >> d"."c".entry"}}' d=$(date +%Y%m%d) file 
2
27.01.2020, 20:12

Надеюсь, это сработает. События идут в файл событий . А сообщения - в stdout.

Сохраните этот файл в myprogram.awk (например):

#!/usr/bin/awk -f

BEGIN {
   s=0;  ### state. Active when parsing inside an event
   nevent=0;  ### Current event number
   printf "" > "events"
}

# Start of event
/^ *Data control raising event/ {
   s=1;
   dentries=0;
   print "*** Event number: " nevent >> "events"
   nevent++
}

# Standard event line
s==1 {
   print >> "events"
}

# DataChangeEntry line
/^ *==== DataChangeEntry/ {
   dentries ++
}

# End of event
s==1 && /^ *\]\]/ {
   s=0;
   print "" >> "events"
   if(dentries==0){
      print "Warning: Event " nevent " has no Data Entries"
   }
}

END {
   print "Total event count: " nevent
}

Вы можете вызвать его различными способами:

  • myprogram.awk inputfile.txt
  • awk -f myprogram.awk inputfile.txt

Sample output:

Warning: Event 3 has no Data Entries
Total event count: 3

Вы можете проверить все события вместе в файле с названием events в рабочем каталоге.

4
27.01.2020, 20:12

Теги

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