次の内容を含むログファイルがあります。
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
date
これを行うには、GNUコマンドを使用できます。文字列を受け取り、その日付を印刷できます。
$ 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
ファイルからを実行してすべて-
をに置き換えます/
。その後、それを渡して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月()の前に2月()も並べ替える必要がある場合は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
ここでのコツは、これを-
フィールド区切り記号として使用し、最初に3番目のフィールド(年)、1番目(月)、2番目(日)にソートすることです。すべてのソートは数字で行われます(-n
オプション)。