我有一个日志文件,其内容如下:
11-12-2014 - 03:03:59AM lat = 41.990516; lon = -93.430704<br>
11-12-2014 - 03:05:15AM lat = 41.001546; lon = -93.443352<br>
11-12-2014 - 03:11:50AM lat = 42.039054; lon = -93.442001<br>
11-12-2014 - 12:08:03AM lat = 41.937911; lon = -93.369249<br>
11-12-2014 - 12:11:29AM lat = 41.949656; lon = -93.329133<br>
11-12-2014 - 12:23:02AM lat = 42.025385; lon = -93.347026<br>
11-12-2014 - 12:29:10AM lat = 41.033341; lon = -93.380586<br>
11-12-2014 - 12:38:08AM lat = 41.036720; lon = -93.436851<br>
11-12-2014 - 12:45:20AM lat = 41.998129; lon = -93.400943<br>
11-12-2014 - 12:53:36AM lat = 41.961489; lon = -93.414624<br>
如何将其转换为 24 小时时间并正确排序?
答案1
和perl
:
$ perl -MTime::Piece -anle '
$F[2] = Time::Piece->strptime($F[2],"%r")->strftime("%H:%M:%S");
push @out, [$F[2]."-".join("-", reverse(split("-",$F[0]))), join(" ",@F)];
END {
print for map { $_->[1] }
sort { $a->[0] cmp $b->[0] } @out;
}' file
11-12-2014 - 00:08:03 lat = 41.937911; lon = -93.369249<br>
11-12-2014 - 00:11:29 lat = 41.949656; lon = -93.329133<br>
11-12-2014 - 00:23:02 lat = 42.025385; lon = -93.347026<br>
11-12-2014 - 00:29:10 lat = 41.033341; lon = -93.380586<br>
11-12-2014 - 00:38:08 lat = 41.036720; lon = -93.436851<br>
11-12-2014 - 00:45:20 lat = 41.998129; lon = -93.400943<br>
11-12-2014 - 00:53:36 lat = 41.961489; lon = -93.414624<br>
11-12-2014 - 03:03:59 lat = 41.990516; lon = -93.430704<br>
11-12-2014 - 03:05:15 lat = 41.001546; lon = -93.443352<br>
11-12-2014 - 03:11:50 lat = 42.039054; lon = -93.442001<br>
答案2
您可以使用 GNUdate
命令来完成此操作。它可以接受字符串并打印出相应的日期:
$ date -d "11/11/2014 04:12:03PM"
Tue Nov 11 16:12:03 CET 2014
但请注意,它不喜欢DD-MM-YYY
:
$ date -d "11-11-2014"
date: invalid date ‘11-11-2014’
因此,首先sed
对您的文件运行 a 以将所有内容替换-
为/
.然后,传递它read
以将每个字段放入一个单独的变量中,进行转换和排序:
$ sed 's#-#/#g' file | while read date _ hour rest; do
echo "$(date -d "$date $hour" +"%F - %R:%S") $rest"
done | sort -h
2014-11-12 - 00:08:03 lat = 41.937911; lon = /93.369249<br>
2014-11-12 - 00:11:29 lat = 41.949656; lon = /93.329133<br>
2014-11-12 - 00:23:02 lat = 42.025385; lon = /93.347026<br>
2014-11-12 - 00:29:10 lat = 41.033341; lon = /93.380586<br>
2014-11-12 - 00:38:08 lat = 41.036720; lon = /93.436851<br>
2014-11-12 - 00:45:20 lat = 41.998129; lon = /93.400943<br>
2014-11-12 - 00:53:36 lat = 41.961489; lon = /93.414624<br>
2014-11-12 - 03:03:59 lat = 41.990516; lon = /93.430704<br>
2014-11-12 - 03:05:15 lat = 41.001546; lon = /93.443352<br>
这适用于您的示例,但如果您还需要将二月 ( 02
) 排序在 11 月 ( 11
) 之前,则会失败。因此,一个技巧是将日期打印为自纪元以来的秒数,对其进行排序,然后将其删除:
$ sed 's#-#/#g' file | while read date _ hour rest; do
printf "%s\t%s %s\n" "$(date -d "$date $hour" +"%s")" "$date - $hour" "$rest"
done | sort | cut -f 2-
11/12/2014 - 12:08:03AM lat = 41.937911; lon = /93.369249<br>
11/12/2014 - 12:11:29AM lat = 41.949656; lon = /93.329133<br>
11/12/2014 - 12:23:02AM lat = 42.025385; lon = /93.347026<br>
11/12/2014 - 12:29:10AM lat = 41.033341; lon = /93.380586<br>
11/12/2014 - 12:38:08AM lat = 41.036720; lon = /93.436851<br>
11/12/2014 - 12:45:20AM lat = 41.998129; lon = /93.400943<br>
11/12/2014 - 12:53:36AM lat = 41.961489; lon = /93.414624<br>
11/12/2014 - 03:03:59AM lat = 41.990516; lon = /93.430704<br>
11/12/2014 - 03:05:15AM lat = 41.001546; lon = /93.443352<br>
11/12/2014 - 03:11:50AM lat = 42.039054; lon = /93.442001<br>
或者,以 24 小时格式打印日期:
$ sed 's#-#/#g' file | while read date _ hour rest; do
printf "%s\t%s %s\n" "$(date -d "$date $hour" +"%s")" \
"$(date -d "$date $hour" +"%F - %R:%S")" "$rest"
done | sort | cut -f 2-
2014-11-12 - 00:08:03 lat = 41.937911; lon = /93.369249<br>
2014-11-12 - 00:11:29 lat = 41.949656; lon = /93.329133<br>
2014-11-12 - 00:23:02 lat = 42.025385; lon = /93.347026<br>
2014-11-12 - 00:29:10 lat = 41.033341; lon = /93.380586<br>
2014-11-12 - 00:38:08 lat = 41.036720; lon = /93.436851<br>
2014-11-12 - 00:45:20 lat = 41.998129; lon = /93.400943<br>
2014-11-12 - 00:53:36 lat = 41.961489; lon = /93.414624<br>
2014-11-12 - 03:03:59 lat = 41.990516; lon = /93.430704<br>
2014-11-12 - 03:05:15 lat = 41.001546; lon = /93.443352<br>
2014-11-12 - 03:11:50 lat = 42.039054; lon = /93.442001<br>
答案3
使用 python 和dateutil
模块 ( pip install dateutil
),您可以直接对日期时间对象进行排序:
#! /usr/bin/env python
import sys
from dateutil.parser import parse
lines = []
for line in open(sys.argv[1]):
d, rest = line[:24], line[24:]
lines.append((parse(d), rest))
for x in sorted(lines):
print x[0], x[1],
从...开始python program.py inputfile
这可以在没有的情况下完成,dateutil
但使用它的优点是您不必指定输入时间格式,只要它不模糊即可。
答案4
我会awk
使用sort
:
awk '{while("date +%T -d" $3|getline x){$3=x}}1' logfile | sort -t- -n -k3 -k1 -k2
首先让我们稍微修改一下日志以具有不同的日期:
11-12-2010 - 03:03:59AM lat = 41.990516; lon = -93.430704
11-12-1998 - 03:05:15AM lat = 41.001546; lon = -93.443352
11-12-2030 - 03:11:50AM lat = 42.039054; lon = -93.442001
11-12-2014 - 12:08:03AM lat = 41.937911; lon = -93.369249
11-12-2014 - 12:11:29AM lat = 41.949656; lon = -93.329133
11-11-2014 - 12:23:02AM lat = 42.025385; lon = -93.347026
11-12-2011 - 12:29:10AM lat = 41.033341; lon = -93.380586
11-12-2011 - 12:38:08AM lat = 41.036720; lon = -93.436851
10-12-2014 - 12:45:20AM lat = 41.998129; lon = -93.400943
11-12-2014 - 12:53:36AM lat = 41.961489; lon = -93.414624
结果将是:
11-12-1998 - 03:05:15 lat = 41.001546; lon = -93.443352
11-12-2010 - 03:03:59 lat = 41.990516; lon = -93.430704
11-12-2011 - 00:29:10 lat = 41.033341; lon = -93.380586
11-12-2011 - 00:38:08 lat = 41.036720; lon = -93.436851
10-12-2014 - 00:45:20 lat = 41.998129; lon = -93.400943
11-11-2014 - 00:23:02 lat = 42.025385; lon = -93.347026
11-12-2014 - 00:08:03 lat = 41.937911; lon = -93.369249
11-12-2014 - 00:11:29 lat = 41.949656; lon = -93.329133
11-12-2014 - 00:53:36 lat = 41.961489; lon = -93.414624
11-12-2030 - 03:11:50 lat = 42.039054; lon = -93.442001
这里的技巧是用作-
字段分隔符,并首先在第三个字段(年)上排序,然后在第一个(月)上排序,然后在第二个(日)上排序。所有排序都是数字(-n
选项)。