Самый простой путь с 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
в течение пронумерованного рабочего дня, независимой от языка опции.
Очень простой подход будет
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
Надеюсь, это сработает. События идут в файл событий
. А сообщения - в 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
в рабочем каталоге.