【问题标题】:Sort by 12-hour time?按 12 小时时间排序?
【发布时间】:2013-08-02 14:46:16
【问题描述】:

今天早上快速(可能是愚蠢的)问题:

我的脚本中输入了如下所示的数据:

03:00P - Doctor appointment.
07:00P - Scheduled entry.
10:30A - Another entry.
11:00A - Daytime medication is due.
11:00P - Nighttime medication is due.
11:30P - Staff meeting.

现在我无法更改数据的来源,并且输出需要看起来相同,但我需要对其进行正确排序。有关解决此问题的任何想法?

谢谢!

【问题讨论】:

  • 您设法避免了有趣的时间:12:05A - Just past midnight and long before 11:00A12:05P - Just past midday and long before 11:00P。接受的答案不能正确处理这些时间。
  • 您可能会发现Convert 12-hour date/time to 24-hour date/time 中的信息对处理该问题很有用。我认为您可能会发现使用 Perl 或 Awk 或 Python 进行预处理以添加包含转换为 24 小时表示法的 AM/PM 时间的列,然后对 24 小时列进行排序,然后(如有必要)将其删除可能是“最好的”,除非 sort 有一个内置选项来处理 AM/PM 时间排序。

标签: bash sorting time


【解决方案1】:

告诉 sort 首先对第六个字符进行排序,然后对第一个到第五个字符进行排序:

sort -k1.6,1.6 -k1.1,1.5

【讨论】:

    【解决方案2】:

    如果您将时间中的AP 放在时间的前面,则只需使用普通的sort 命令即可正确排序。所以可能是这样的:

    awk '{print substr($1,6), $0}' < input  | sort | cut -d' ' -f2-
    

    awk 命令生成如下输出:

    P 03:00P - Doctor appointment.
    P 07:00P - Scheduled entry.
    A 10:30A - Another entry.
    A 11:00A - Daytime medication is due.
    P 11:00P - Nighttime medication is due.
    P 11:30P - Staff meeting.
    

    我们然后sort,然后去掉前缀。

    【讨论】:

    • 嗯,我更喜欢@choroba 的解决方案。
    【解决方案3】:

    这是一个基于简单 Perl 脚本的解决方案,该脚本源自对 Convert 12-hour date/time to 24-hour date/time 的回答。

    来源s12.pl

    #!/usr/bin/env perl
    use strict;
    use warnings;
    
    sub time_12h_to_24h
    {
        my($t12) = @_;
        my($hh,$mm,$ampm) = $t12 =~ m/^(\d\d?):(\d\d?)\s*([AP]M?)/i;
        $hh = ($hh % 12) + (($ampm =~ m/AM?/i) ? 0 : 12);
        return sprintf("%.2d:%.2d", $hh, $mm);
    }
    
    while (<>)
    {
        my($time_12h, $entry) = split / - /;
        my $time_24h = time_12h_to_24h($time_12h);
        print "$time_24h $time_12h - $entry";
    }
    

    请注意,代码同时接受 { AM, PM } 和 { A, P } 并且对于 AM/PM 指示符在大写和小写之间是中性的,并且忽略之间的空格时间和 AM/PM 指示器。

    输入数据

    此数据集包含 12:05A 和 12:05P 的行以及来自问题的数据。

    03:00P - Doctor appointment.
    07:00P - Scheduled entry.
    10:30A - Another entry.
    11:00A - Daytime medication is due.
    11:00P - Nighttime medication is due.
    11:30P - Staff meeting.
    12:05A - Just past midnight and long before 11:00A.
    12:05P - Just past midday and long before 11:00P.
    

    双重过滤输出

    $ perl s12.pl data | sort | sed 's/^..:.. //'
    12:05A - Just past midnight and long before 11:00A.
    10:30A - Another entry.
    11:00A - Daytime medication is due.
    12:05P - Just past midday and long before 11:00P.
    03:00P - Doctor appointment.
    07:00P - Scheduled entry.
    11:00P - Nighttime medication is due.
    11:30P - Staff meeting.
    $
    

    未过滤的输出

    $ perl s12.pl data | sort
    00:05 12:05A - Just past midnight and long before 11:00A.
    10:30 10:30A - Another entry.
    11:00 11:00A - Daytime medication is due.
    12:05 12:05P - Just past midday and long before 11:00P.
    15:00 03:00P - Doctor appointment.
    19:00 07:00P - Scheduled entry.
    23:00 11:00P - Nighttime medication is due.
    23:30 11:30P - Staff meeting.
    $
    

    请注意,通过将键列(24 小时时间列)放在输出的首位,sort 命令得到了简化(通常,它也加快了排序速度)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-07
      • 2014-06-29
      • 2012-04-09
      • 2021-12-24
      相关资源
      最近更新 更多