在 linux 命令行上按时间戳对日志文件进行排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7347054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
sort logfile by timestamp on linux command line
提问by markus
I have a logfile with entries like:
我有一个日志文件,其中包含以下条目:
...
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!
...
How can I sort the file with linux command line tools by the timestamp in each row decending?
如何使用 linux 命令行工具按每行降序中的时间戳对文件进行排序?
采纳答案by gpojd
Use sort's -k flag:
使用sort的 -k 标志:
sort -k1 -r freeswitch.log
That will sort the file, in reverse, by the first key (i.e. freeswitch.log:2011-09-08 12:21:07.282236). If the filename is always the same (freeswitch.log), then it should sort by the date.
这将按第一个键对文件进行反向排序(即 freeswitch.log:2011-09-08 12:21:07.282236)。如果文件名始终相同 (freeswitch.log),则应按日期排序。
回答by dawnsong
The log file seems ascending, you can
日志文件似乎是升序的,你可以
tac yourlogfile
which would reversely show your log file.
这将反向显示您的日志文件。
回答by denolk
I guess the log file appends new data at the end. If so, you may read the file in reverse. Try with tail -ror catcommand.
我猜日志文件最后会附加新数据。如果是这样,您可以反向读取文件。尝试使用tail -r或cat命令。
回答by Patrick B.
You can reverse the sort with
您可以使用反向排序
sort -r
回答by sorpigal
Crude but effective technique: Prefix each line with a numeric representation of the date, sort numerically, then remove the extra info.
粗略但有效的技术:在每一行前面加上日期的数字表示,按数字排序,然后删除额外的信息。
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=""
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
Note: Requires GNU date.
注意:需要 GNU 日期。
If the output at this point is the reverse of what you want it is simple to pipe through tac
or to modify the script to also pass -r
to sort
.
如果此时的输出与您想要的相反,则很容易通过管道tac
或修改脚本以也传递-r
到sort
.
EDIT: I missed the part where the filename was literally on each line. Updated version will now actually work.
编辑:我错过了文件名在每一行上的部分。更新后的版本现在可以实际工作了。
回答by bash-o-logist
You can try using sort
您可以尝试使用排序
sort -k1,2 file
回答by Stuart P. Bentley
Use sort's --stable
, --reverse
, and --key
options:
使用排序的--stable
,--reverse
和--key
选项:
sort --stable --reverse --key=1,2 freeswitch.log
(For non-didactic purposes, this can be shortened to -srk1,2
.)
(对于非教学目的,这可以缩短为-srk1,2
。)
The sort
command (as you might expect) outputs each line of the named files (or STDIN) in sorted order. What each of these options does:
该sort
命令(如您所料)按排序顺序输出命名文件(或 STDIN)的每一行。每个选项的作用:
- The
--reverse
option tellssort
to sort lines with greater values (later dates) higher, rather than lower. It's assumed, based on other answers, that this is what you mean by "descending" (even though this kind of sorting would normally be considered "ascending"). If you want to sort the lines in chronological order, you would omit this option. - The
--key=1,2
option tellssort
to only use the first two whitespace-separated "fields" (the "freeswitch.log:"-prefixed date, and the time) as the key for sorting. It is important that you specify the lastfield to use, even if you are only sorting by one field (for instance, if each line kept time and date together in an ISO-8601 standard field likefreeswitch.log 2011-09-08T12:21:07.282236
, you would use-k 2,2
), as, by default, the fields used by a key extend to the end of the line. - The
--stable
option tellssort
to not perform "last-resort ordering". Without this option, a line with two equal keys (as specified with the--keys
option) will then be sorted according to the entire line, meaning that the filename and/or contentwill change the sort order of the lines.
- 该
--reverse
选项告诉sort
将具有更大值(较晚日期)的行排序为更高,而不是更低。根据其他答案,假设这就是您所说的“降序”(即使这种排序通常被认为是“升序”)。如果要按时间顺序对行进行排序,则可以省略此选项。 - 该
--key=1,2
选项告诉sort
只使用前两个空格分隔的“字段”(“freeswitch.log:”-前缀日期和时间)作为排序的键。指定要使用的最后一个字段很重要,即使您只按一个字段排序(例如,如果每行在 ISO-8601 标准字段中将时间和日期放在一起,例如freeswitch.log 2011-09-08T12:21:07.282236
,您将使用-k 2,2
),如,通过默认情况下,键使用的字段会扩展到行尾。 - 该
--stable
选项告诉sort
不执行“最后的排序”。如果没有此选项,则具有两个相等键(由--keys
选项指定)的行将根据整行进行排序,这意味着文件名和/或内容将更改行的排序顺序。
It is important to specify both extents of the --key
, as well as the --stable
option. Without them, multiple lines of output that occurred at the same time (in other words, a multi-line message) would be sorted according to the content of the message (without the second field in --key
) and/or the filename (without --stable
, if the filename is a separate field, as described below).
指定的两个程度是很重要的--key
,还有的--stable
选项。没有它们,同时发生的多行输出(换句话说,多行消息)将根据消息的内容(没有 中的第二个字段--key
)和/或文件名(没有--stable
,如果文件名是一个单独的字段,如下所述)。
In other words, a log message like this:
换句话说,像这样的日志消息:
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?
would get "sorted" into:
会被“分类”为:
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:
This is "sorted"(because "c" comes before "d", and "S" comes before "W"), but it's not in order. Specifying --stable
(and keeping your --key
bounded) will skip the extra sorting and preserve the order, which is what you want.
这是“排序的”(因为“c”在“d”之前,而“S”在“W”之前),但它不是有序的。指定--stable
(并保持--key
有界)将跳过额外的排序并保留 order,这正是您想要的。
Also, sorting by this combined filename-and-date field will only work if every line in your output starts with the same filename. Given the syntax you posted, if your input has multiple, different filenames that you want to ignore in sorting, you need to use a program like sed
to convert the filename to its own space-separated field, then pipe the converted lines to sort
(after which you may then convert the field separators back):
此外,仅当输出中的每一行都以相同的文件名开头时,才能按此组合的文件名和日期字段进行排序。鉴于您发布的语法,如果您的输入有多个不同的文件名,您希望在排序时忽略这些文件名,则需要使用类似程序sed
将文件名转换为其自己的空格分隔字段,然后将转换后的行通过管道传输到sort
(之后然后您可以将字段分隔符转换回来):
sed 's/:/ /' freeswitch.log | sort -srk2,3 | sed 's/ /:/'
Note that the fields used by the key are changed to 2,3
, skipping the first (filename) field.
请注意,键使用的字段更改为2,3
,跳过第一个(文件名)字段。