2012-07-18 165 views
3

我有包含数十万条记录的文本文件。其中一个字段是日期字段。 是否有任何方法基于日期字段对文件进行排序?unix中的排序日期字段

09-APR-12 04.08.43.632279000 AM 
19-MAR-12 03.53.38.189606000 PM 
19-MAR-12 03.56.27.933365000 PM 
19-MAR-12 04.00.13.387316000 PM 
19-MAR-12 04.04.45.168361000 PM 
19-MAR-12 03.54.32.595348000 PM 
27-MAR-12 10.28.14.797580000 AM 
28-MAR-12 12.28.02.652969000 AM 
27-MAR-12 07.28.02.828746000 PM 

输出应是

19-MAR-12 03.53.38.189606000 PM 
19-MAR-12 03.54.32.595348000 PM 
19-MAR-12 03.56.27.933365000 PM 
19-MAR-12 04.00.13.387316000 PM 
19-MAR-12 04.04.45.168361000 PM 
27-MAR-12 10.28.14.797580000 AM 
27-MAR-12 07.28.02.828746000 PM 
28-MAR-12 12.28.02.652969000 AM 
09-APR-12 04.08.43.632279000 AM 

我试图sort命令订购日期(以日期字段作为一个字符串),但它是不是给正确的输出。

回答

5

试试这个:

INPUT.TXT

09-APR-12 04.08.43.632279000 AM 
19-MAR-12 03.53.38.189606000 PM 
19-MAR-12 03.56.27.933365000 PM 
19-MAR-12 04.00.13.387316000 PM 
19-MAR-12 04.04.45.168361000 PM 
19-MAR-12 03.54.32.595348000 PM 
27-MAR-12 10.28.14.797580000 AM 
28-MAR-12 12.28.02.652969000 AM 
27-MAR-12 07.28.02.828746000 PM 

代码

sort -t "-" -k 3 -k 2M -nk 1 Input.txt 

输出

19-MAR-12 03.53.38.189606000 PM 
19-MAR-12 03.54.32.595348000 PM 
19-MAR-12 03.56.27.933365000 PM 
19-MAR-12 04.00.13.387316000 PM 
19-MAR-12 04.04.45.168361000 PM 
27-MAR-12 07.28.02.828746000 PM 
27-MAR-12 10.28.14.797580000 AM 
28-MAR-12 12.28.02.652969000 AM 
09-APR-12 04.08.43.632279000 AM 
+0

这输出'27-MAR-12 07 ... PM'在'27-MAR-12 10 ... AM'之前。 – 2012-07-18 15:08:32

6

Chronicle的解决方案很接近,但错过了AM/PM的区别,排序27-MAR-12 07.28.02.828746000 PM之前27-MAR-12 10.28.14.797580000 AM。这可以修改:

sort -t- -k 3.1,3.2 -k 2M -k 1n -k 3.23,3.24 

但是,这仍然是非常脆弱的。将日期转换为纪元时间并进行数值比较会更好。

+0

+1 O是的..我错过了...谢谢... :) – Debaditya 2012-07-18 15:39:42

+0

+1特别是建议转换为理智的日期格式。 – tripleee 2012-07-19 06:17:11

0

这个脚本通过各种大纪元时间纳秒分辨率:

awk '{ 
    t = gensub(/\.([0-9]{2})\./, ":\\1:", 1, $0); 
    command = "date +%s%N -d \x022" t "\x022"; 
    command | getline t; 
    close(command); 
    print t, $0; 
}' unsorted.txt | sort -n -k 1 | cut -d ' ' -f 2- > sorted.txt 
0

你可以使用日期,通常可能是一个不错的主意,特别是如果你不需要担心微秒,否则可能可能会缩短微秒并将其作为辅助排序字段进行排序。

while read a; do 
grep "^${a}" input.txt; 
done < <(sed 's/\./:/;s/\./:/' input.txt | xargs -n3 -I{} date -d"{}" +%s | sort | xargs -n1 -I{} date -d @'{}' +'%d-%^h-%y %I.%M.%S')