关于bash:按12小时的时间排序?

Sort by 12-hour time?

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

我的脚本中有如下数据:

1
2
3
4
5
6
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.

现在我无法更改数据源,输出需要看起来相同,但我需要对其进行正确的排序。有什么解决办法吗?

谢谢!


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

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

这里有一个基于从答案派生的简单Perl脚本的解决方案,将12小时的日期/时间转换为24小时的日期/时间。

资料来源:s12.pl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/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";
}

注意,代码同时接受AMPMAP并且在AM/PM指示器的大小写之间是中性的,并且忽略了时间和AM/PM指示器之间的空格。

输入数据

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

1
2
3
4
5
6
7
8
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.

双滤波输出

1
2
3
4
5
6
7
8
9
10
$ 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.
$

未筛选的输出

1
2
3
4
5
6
7
8
9
10
$ 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命令(而且,通常,它也会加快排序速度)。


如果您从时间上获取AP,并将其放在时间前面,则仅使用正常的sort命令即可正确排序。所以可能是这样:

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

awk命令生成如下输出:

1
2
3
4
5
6
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去掉前缀。