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

标签 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.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/

相关文章:

bash - 将 MacOS 上的/bin/bash 升级到 v5+

mysql - 使用Shell脚本远程拉取Mysql数据

linux - -bash :/bin/ls: Argument list too long if there is a lot of PATH

linux - Unix 中的无缓冲 I/O

linux - 如何打开 .sess 文件?

linux - Nginx无法打开certs文件夹中的cert.pem文件

git - 了解基本的 git 钩子(Hook)

c++ - 如何使用 LD_LIBRARY_PATH 和链接使其真正正确?

linux - Bash 变量冲突

linux - Unix 删除最后两个标记