如何通过排除 header 根据日期字段对数据进行排序

How to sort data based on date field by excluding header

我有一个场景,文件中有以下数据 需要根据日期列进行排序,第一行是 headers 它不应该被排序

NAME|AGE|COURSE|DATES
v1|31|MC|12 JUL 2019
v2|33|MB|4  JUL 2019
v3|12|GG|13 JUL 2019
v4|21|JJ|7  JUL 2019

我的代码:

sort -n -k k4 /d/file.txt 

上面的代码没有对我的数据进行排序

预期输出:

NAME|AGE|COURSE|DATES
v4|21|JJ|7  JUL 2019
v2|33|MB|4  JUL 2019
v1|31|MC|12 JUL 2019
v3|12|GG|13 JUL 2019

方法是使用 Command Grouping,您可以从输入流中提取 header,打印它,然后使用剩余数据:

{
    IFS= read -r header
    echo "$header"
    sort ...
} < file.txt

但是,使用这种格式对日期进行排序很棘手。这是您必须执行的操作,以便按时间顺序对输出进行排序。这假设 GNU 排序:

$ cat file.txt          # I added a couple of extra records
NAME|AGE|COURSE|DATES
v1|31|MC|12 JUL 2019
v2|33|MB|4  JUL 2019
v3|12|GG|13 JUL 2019
v4|21|JJ|7  JUL 2019
11|22|33|1  JUL 2020
aa|bb|cc|10 AUG 2019

$ {
    IFS= read -r header
    echo "$header"
    sort -t'|' -n -s -k4 | sort -M -s -k 2,2 | sort -n -s -k 3,3
} < file.txt
NAME|AGE|COURSE|DATES
v2|33|MB|4  JUL 2019
v4|21|JJ|7  JUL 2019
v1|31|MC|12 JUL 2019
v3|12|GG|13 JUL 2019
aa|bb|cc|10 AUG 2019
11|22|33|1  JUL 2020

它使用 GNU 排序“稳定”选项,因此您首先按天排序,然后按月排序,然后按年排序。

借用@glennjackman 的示例输入,这将适用于任何版本的强制性 Unix 工具 awk、排序和剪切:

$ awk '
    BEGIN { FS="|"; OFS="\t" }
    {
        split($NF,d," ")
        mthNr = (index("JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC",d[2])+2)/3
        print (NR>1), d[3], mthNr, d[1], NR, [=10=]
    }
' file.txt |
sort -k1,1n -k2,2n -k3,3n -k4,4n -k5,5n |
cut -f6-
NAME|AGE|COURSE|DATES
v2|33|MB|4  JUL 2019
v4|21|JJ|7  JUL 2019
v1|31|MC|12 JUL 2019
v3|12|GG|13 JUL 2019
aa|bb|cc|10 AUG 2019
11|22|33|1  JUL 2020