grep файл журнала, начиная с определенного времени и до конца файла


3

У меня есть файл журнала, который имеет дату и время в начале каждой строки.

Мне нужно искать файл журнала, начиная с определенного времени до конца файла.

Например:

Starting point: July 29 2018 21:00:00
End point     : end of file

Я обеспокоен тем, что даже если шаблон July 29 2018 21:00:00не существует, я все равно получаю грань между, например, July 29 2018 21:05:11так как это все еще за пределами July 29 2018 21:00:00.

Есть awkили sedработа для этого?



Это то, что может выполнить ausearch?
SPITFINGERS

Ответы:


2

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

$ cat file
June 5 2018 00:00:00 do not print
July 29 2018 20:59:59 do not print
July 29 2018 21:00:00 print me
July 29 2018 21:00:01 print me

$ perl -MTime::Piece -sane '
    BEGIN {
        $start = Time::Piece->strptime($startdate, "%B %e %Y %T");
    }
    # the string "@F[0..3]" is the first 4 words on the line
    $time = Time::Piece->strptime("@F[0..3]", "%B %e %Y %T");
    print if $time >= $start;
' -- -startdate="July 29 2018 21:00:00" file
July 29 2018 21:00:00 print me
July 29 2018 21:00:01 print me

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

perl -MTime::Piece -sane '
    BEGIN {
        $start = Time::Piece->strptime($startdate, "%B %e %Y %T");
    }
    unless ($go) {
        $time = Time::Piece->strptime("@F[0..3]", "%B %e %Y %T");
        $go = $time >= $start;
    }
    print if $go;
' -- -startdate="July 29 2018 21:00:00" file

+1 по сравнению с моим решением это просто супербыстро. awkс системным вызовом dateбыло еще медленнее.
pLumo

GNU awk (gawk) имеет встроенные функции времени , но время синтаксического анализа все еще довольно ручное.
Гленн Джекман

1

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

grepfromdate() {
    readarray f < $1
    fromdate=$(date +%s -d "$2")
    for (( lineno=${#f[@]}-1 ; lineno>=0; lineno-- )) ; do
        line=${f[$lineno]}
        time_from_line=$(echo "$line" | grep -o "^[A-Z][a-z]* [0-9][0-9] [0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]")
        [[ $(date +%s -d "$time_from_line") -gt $fromdate ]] && echo "$line" || break
    done | tac
}

Использование:
grepfromdate "filename" "July 29 2018 21:00:00"

Вы можете передать любой формат даты, который dateможет читать, например 2018-07-01. Если формат даты изменяется, вы можете изменить grepшаблон в соответствии с этим.


это медленно, так как нужно открывать файл для каждой строки
pLumo

он также должен вызывать sed, grep и date (дважды) для каждой строки.
Гленн Джекман

1
Я изменил сценарий и теперь прочитал файл в массив, чтобы удалить вызов sed, измененная дата будет вызвана только один раз. Но все же одна дата и один grep для каждой строки. Тем не менее, это удвоило производительность ;-)
pLumo

0

Вы можете искать первую строку, соответствующую определенной строке (т. July 29 2018 21:Е. Все после 9 вечера). Если у вас есть этот номер строки, вы можете tailфайл, начиная с найденного номера строки.

   $ man tail
   -n, --lines=[+]NUM
          output the last NUM lines, instead of the last 10; or use -n +NUM to output starting with line NUM

мой пример:

$ log=/var/log/syslog

# get line number
$ first_line=$(grep -no "Aug 14 08:" $log | tail -n1 | cut -d: -f1)

# count the lines from $first_line to EOF
$ tail -n +$first_line $log | wc -l
24071

# output the content starting with $first_line
$ tail -n +$first_line $log

# line count of the whole file:
$ wc -l $log
70896 /var/log/syslog

0

С sedтобой можно сделать

sed -n '/July 29 2018 21:/,/$!d/p' file

Это даст вам все строки между 29 июля 2018 года 21: ** и последней строкой файла

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.