我有一个包含以下条目的日志文件:
...
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 命令行工具按每行中的时间戳降序对文件进行排序?
最佳答案
使用sort的 --stable
、--reverse
和 --key
选项:
sort --stable --reverse --key=1,2 freeswitch.log
(出于非教学目的,这可以缩短为 -srk1,2
。)
sort
命令(如您所料)按排序顺序输出命名文件(或 STDIN)的每一行。每个选项的作用:
--reverse
选项告诉sort
将值较大(较晚的日期)的行排序更高,而不是更低。根据其他答案,假设这就是“降序”的意思(即使这种排序通常被认为是“升序”)。如果您想按时间顺序对行进行排序,则可以省略此选项。--key=1,2
选项告诉sort
仅使用前两个以空格分隔的“字段”(“freeswitch.log:”前缀日期和时间)作为排序的关键。指定要使用的 last 字段很重要,即使您只按一个字段排序(例如,如果每一行在 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
,跳过第一个(文件名)字段。
关于linux - 在linux命令行上按时间戳对日志文件进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7347054/