awk огромный лог-файл сзади до отметки времени - PullRequest
3 голосов
/ 29 апреля 2011

Я хочу получить последнюю часть с заданной отметки времени "t0" из возможного огромного файла журнала (> 50..1000mb):

     __________________
    |1 xxx xxx ...     |
    |2 xxx ...         |     uninteresting part
    |4 ...             |
    |...               |
 ___|423 ...           | ___ timestamp t0
    |425 xxx ...       |
    |437 ...           |
    |...               |     <-- i want this part ( from t0 to EOF)
    |__________________|

и дополнительным ограничением является то, что я хочу сделать это с помощью простых команд bash. простое решение может быть:

awk '$1 > 423' file.log

но при этом сканируется весь файл со всеми неинтересными строками. есть команда tail , но я просто могу дать ему количество последних строк, которые я хочу, которых я не знаю - я просто знаю метку времени. есть ли способ «проснуться» сзади и остановить обработку, когда первая метка времени не совпадает?

Ответы [ 4 ]

4 голосов
/ 30 апреля 2011

TAC твой друг здесь:

tac file.log | awk '{ if ($1 >= 423) print; else exit; }' | tac

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

1 голос
/ 29 апреля 2011

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

Чтобы ваш огромный файл был примерно таким:

~$ cat > file << EOF
rubish
n lines of rubish
more rubish
timestamp regexp
interesting
n interesting lines
interesting
end of file
EOF

Если вы можете получить выполнимое регулярное выражение для искомой отметки времени, вы можете получить нужную часть с помощью sed:

~$ sed -n '/timestamp regexp/,$ {p}' file
timestamp regexp
interesting
n interesting lines
interesting
end of file
1 голос
/ 29 апреля 2011

Используя стандартные команды Unix, вы ничего не можете сделать, кроме как сканировать весь файл.Если вы пишете свою собственную программу, вы можете выполнить двоичный поиск по файлу:

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

Вы можете даже выполнить поиск с помощьюлинейная интерполяция, а не чистый двоичный поиск, если метки времени являются чистыми числами;Вероятно, не стоит дополнительного кодирования, если штампы более сложные, но это зависит от того, как часто вам это понадобится.

Действительно, если вы не собираетесь делать это много и можетеЧтобы продемонстрировать, что производительность является проблемой, я бы выбрал простое решение awk.

0 голосов
/ 29 апреля 2011

вы можете опрашивать, пока не нажмете "423".Просто гипотетический пример (не проверено)

n=100 # number of lines you want to go back
while true
do
  if tail -$n file | grep -q "423" ;then
     tail -$n file | awk '$1>423'
     break
  else
     ((n+=100)) # increment every 100 lines
  fi
done
...