【问题标题】:Sorting date field in unix在 unix 中对日期字段进行排序
【发布时间】:2012-07-18 07:30:40
【问题描述】:

我有一个包含数十万条记录的文本文件。其中一个字段是日期字段。 有没有办法根据日期字段对文件进行排序?

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 命令对日期进行排序(将日期字段作为字符串),但它没有给出正确的输出。

【问题讨论】:

    标签: bash shell unix sorting


    【解决方案1】:

    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
    

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

    【讨论】:

      【解决方案2】:

      试试这个:

      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
      

      【讨论】:

      • 这在27-MAR-12 10 ... AM之前输出27-MAR-12 07 ... PM
      【解决方案3】:

      此脚本以纳秒分辨率按纪元时间排序:

      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
      

      【讨论】:

        【解决方案4】:

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

        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')
        

        【讨论】:

          猜你喜欢
          • 2011-07-11
          • 1970-01-01
          • 2011-09-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-03
          • 2011-10-30
          相关资源
          最近更新 更多