在linux命令行上按时间戳对日志文件排序

在linux命令行上按时间戳对日志文件排序,linux,bash,shell,command-line,logging,Linux,Bash,Shell,Command Line,Logging,我有一个日志文件,其中包含如下条目: ... 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

我有一个日志文件,其中包含如下条目:

...    
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命令行工具按每行的时间戳对文件进行排序?

日志文件似乎是升序的,您可以

tac yourlogfile

这将反向显示您的日志文件。

我猜日志文件会在末尾追加新数据。如果是这样,您可以反向读取该文件。
尝试使用tail-rcat命令

您可以使用

sort -r

粗糙但有效的方法:在每行前面加上日期的数字表示,按数字排序,然后删除多余的信息

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-
而IFS=''read-r name_date training;do date=$(剪切-d:-f2使用s-k标志:

sort -k1 -r freeswitch.log
这将按第一个键(即freeswitch.log:2011-09-08 12:21:07.282236)对文件进行反向排序。如果文件名始终相同(freeswitch.log),则应按日期排序。

您可以尝试使用排序

sort -k1,2 file
使用的
--稳定
--反转
--键
选项:

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
中没有第二个字段)和/或文件名对同时发生的多行输出(换句话说,多行消息)进行排序(如果文件名是一个单独的字段,则不带
--稳定
,如下所述)

换句话说,这样的日志消息:

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?
将“分类”为:

这是“排序的”(因为“c”在“d”之前,“S”在“W”之前),但它不符合顺序。指定
--stable
(并保持
--key
有界)将跳过额外的排序并保留顺序,这正是您想要的


此外,仅当输出中的每一行都以相同的文件名开头时,按此组合文件名和日期字段进行排序才有效。根据您发布的语法,如果您的输入有多个不同的文件名,您希望在排序时忽略这些文件名,则需要使用类似于
sed
的程序将文件名转换为自己的空格分隔字段d、 然后将转换后的行通过管道传输到排序(之后可以将字段分隔符转换回):


请注意,键使用的字段更改为
2,3
,跳过第一个(文件名)字段。

条目没有按时间戳完全排序是的,空格是公共分隔符吗?不,它没有附加数据,我已经将我要分析的行从原始日志文件grep到一个新文件中。但是如何告知按行中的时间戳排序。注意它们还没有排序(我在问题中更改了它)如果我对您的评论理解正确,这个答案是:grep ftdm_queue.c freeswitch.log | sort-r#这是一个猜测,因为您提供了完整的命令行。如果不指定结束字段或
-s
标志,
-k1
实际上是没有意义的。请参阅中的解释。即使指定了结束字段,最后的比较son使它如此
-k1,2
最终没有什么意义。请参阅中对
-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:
sed 's/:/ /' freeswitch.log | sort -srk2,3 | sed 's/ /:/'