Сортировать файл журнала по метке времени в командной строке linux

У меня есть файл журнала с такими записями, как:

...    
freeswitch.log:2011-09-08 12:21:07.282236 [ERR] ftdm_queue.c:136 Failed to enqueue obj 0x7f2cda3525c0 in queue 0x7f2ce8005990, no more room! windex == rindex == 58!
freeswitch.log:2011-08-08 13:21:07.514261 [ERR] ftdm_queue.c:136 Failed to enqueue obj 0x7f2cda354460 in queue 0x7f2ce8005990, no more room! windex == rindex == 58!
freeswitch.log:2011-06-04 16:21:08.998227 [ERR] ftdm_queue.c:136 Failed to enqueue obj 0x7f2cda356300 in queue 0x7f2ce8005990, no more room! windex == rindex == 58! 
freeswitch.log:2011-09-08 12:21:10.374238 [ERR] ftdm_queue.c:136 Failed to enqueue obj 0x7f2cda3581a0 in queue 0x7f2ce8005990, no more room! windex == rindex == 58!
...

Как я могу сортировать файл с помощью средств командной строки linux по метке времени в каждой строке?

Ответ 1

Используйте sort -k флаг:

sort -k1 -r freeswitch.log

Это будет сортировать файл в обратном порядке с помощью первого ключа (то есть freeswitch.log: 2011-09-08 12: 21: 07.282236). Если имя файла всегда одно и то же (freeswitch.log), оно должно сортироваться по дате.

Ответ 2

Используйте sort --stable, --reverse и --key параметры:

sort --stable --reverse --key=1,2 freeswitch.log

(Для недикатических целей это можно сократить до -srk1,2.)

Команда sort (как и следовало ожидать) выводит каждую строку именованных файлов (или STDIN) в отсортированном порядке. Что каждый из этих вариантов делает:

  • Опция --reverse сообщает sort сортировать строки с большими значениями (более поздние даты) выше, а не ниже. На основании других ответов предполагалось, что это то, что вы подразумеваете под "нисходящим" (хотя этот вид сортировки обычно считается "восходящим" ). Если вы хотите отсортировать строки в хронологическом порядке, вы опустите эту опцию.
  • Опция --key=1,2 сообщает sort использовать только первые два поля, разделенные пробелами ( "freeswitch.log:" - префиксная дата и время) в качестве ключа для сортировки. Важно указать последнее поле для использования, даже если вы только сортируете по одному полю (например, если каждая строка содержала время и дату вместе в стандартном поле ISO-8601, например freeswitch.log 2011-09-08T12:21:07.282236, вы использовали бы -k 2,2), так как по умолчанию поля, используемые ключом, расширяются до конца строки.
  • Опция --stable сообщает sort не выполнять "закат последнего курорта". Без этой опции строка с двумя равными ключами (как указано с опцией --keys) будет сортироваться в соответствии со всей строкой, что означает, что имя файла и/или содержимое изменят порядок сортировки строк.

Важно указать как экстенты --key, так и опцию --stable. Без них несколько строк вывода, которые произошли в одно и то же время (другими словами, многострочное сообщение), будут сортироваться в соответствии с содержимым сообщения (без второго поля в --key) и/или имени файла ( без --stable, если имя файла является отдельным полем, как описано ниже).

Другими словами, сообщение журнала похоже на следующее:

freeswitch.log:2011-09-08 12:21:10.374238 Warning: Syntax error on line 20:
freeswitch.log:2011-09-08 12:21:10.374238
freeswitch.log:2011-09-08 12:21:10.374238    My[brackets(call)
freeswitch.log:2011-09-08 12:21:10.374238               ^
freeswitch.log:2011-09-08 12:21:10.374238 Suggestion:
freeswitch.log:2011-09-08 12:21:10.374238   did you forget to
freeswitch.log:2011-09-08 12:21:10.374238   close your brackets?

будет "сортироваться" на:

freeswitch.log:2011-09-08 12:21:10.374238
freeswitch.log:2011-09-08 12:21:10.374238               ^
freeswitch.log:2011-09-08 12:21:10.374238   close your brackets?
freeswitch.log:2011-09-08 12:21:10.374238   did you forget to
freeswitch.log:2011-09-08 12:21:10.374238    My[brackets(call)
freeswitch.log:2011-09-08 12:21:10.374238 Suggestion:
freeswitch.log:2011-09-08 12:21:10.374238 Warning: Syntax error on line 20:

Это "отсортировано" (потому что "c" предшествует "d", а "S" - до "W" ), но это не в порядке. Указание --stable (и сохранение вашего --key ограничено) пропустит дополнительную сортировку и сохранит порядок, который вы хотите.


Кроме того, сортировка по этому комбинированному полю имени и имени будет работать только в том случае, если каждая строка в вашем выпуске начинается с того же имени файла. Учитывая синтаксис, который вы опубликовали, если ваш ввод содержит несколько разных имен файлов, которые вы хотите игнорировать при сортировке, вам необходимо использовать такую ​​программу, как sed, чтобы преобразовать имя файла в свое собственное поле, разделенное пробелом, а затем передать преобразованные строки в sort (после чего вы можете преобразовать разделители полей назад):

sed 's/:/ /' freeswitch.log | sort -srk2,3 | sed 's/ /:/'

Обратите внимание, что поля, используемые ключом, меняются на 2,3, пропуская первое (имя файла) поле.

Ответ 3

Вы можете отменить сортировку с помощью

sort -r

Ответ 4

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

Oneliner:

while IFS=' ' read -r name_date trailing ; do date=$(cut -d: -f2 <<<"$name_date") ; printf '%s:%s\n' $(date -d "$date" +%s) "$name_date $trailing" ; done < freeswitch.log | sort -k1 -t: | cut -d: -f2-

Shell script:

#!/usr/bin/env bash

logfile="$1"

if [ -f "$logfile" ] ; then
    while IFS=' ' read -r name_date trailing ; do
            date=$(cut -d: -f2 <<<"$name_date")
        printf '%s:%s\n' $(date -d "$date" +%s) "$name_date $trailing"
    done < "$logfile" | sort -k1 -t: | cut -d: -f2-
fi

Примечание. Требуется дата GNU.

Если вывод в этой точке обратнее того, что вы хотите, просто пропустить через tac или изменить script, чтобы также передать -r в sort.

EDIT: я пропустил ту часть, где имя файла было буквально на каждой строке. Обновленная версия теперь будет работать.

Ответ 5

Вы можете попробовать использовать сортировку

sort -k1,2 file

Ответ 6

Файл журнала кажется восходящим, вы можете

tac yourlogfile

который в свою очередь покажет ваш файл журнала.

Ответ 7

Я думаю, файл журнала добавляет новые данные в конец. Если это так, вы можете прочитать файл в обратном порядке. Попробуйте выполнить команду tail -r или cat.