通过shell脚本根据AM/PM对日期时间字段进行排序[重复]

t0ybt7op  于 11个月前  发布在  Shell
关注(0)|答案(2)|浏览(143)

此问题在此处已有答案

Sorting date field in unix(5个答案)
昨天就关门了。
我试图根据日期和时间对这两行进行反向排序,我使用了下面的命令,它工作正常,但不考虑AM和PM,因此下面的两行没有正确排序,因为第一行的时间是10 AM,而第二行是2 PM
指挥官:

sort -t',' -k2,2 -k7,7r file.csv

字符串
线条:
排序前:

field1,field2,field3,field4,field5,field6,19-NOV-23 10.58.03.000000 AM
field1,field2,field3,field4,field5,field6,19-NOV-23 02.48.47.000000 PM


排序后的行(相同排列)

field1,field2,field3,field4,field5,field6,19-NOV-23 10.58.03.000000 AM
field1,field2,field3,field4,field5,field6,19-NOV-23 02.48.47.000000 PM

b4lqfgs4

b4lqfgs41#

man sort(GNU排序):

-k, --key=KEYDEF
       sort via a key; KEYDEF gives location and type

KEYDEF  is F[.C][OPTS][,F[.C][OPTS]] for start and stop position, where
F is a field number and C a character position in the field;  both  are
origin 1, and the stop position defaults to the line's end. - -  
OPTS is one or more single-letter ordering options [bdfgiMhnRrV] - -

字符串
数据中的字段7:

1111111111222222222
1234567890123456789012345678
19-NOV-23 10.58.03.000000 AM
19-NOV-23 02.48.47.000000 PM


首先定义反向(或在OPTS),字段分隔符和年份(字段7,位置8和9,数字):

sort -r -t, -k7.8,7.9n file


然后是月份(GNU排序中的M排序选项):

sort -r -t, -k7.8,7.9n -k7.4,7.6M file


然后是当天和AM/PM(实际上是A/P):

sort -r -t, -k7.8,7.9n -k7.4,7.6M -k7.1n,7.2n -k7.27 file


然后是时间的一部分(用于锻炼)。
上面你得到:

field1,field2,field3,field4,field5,field6,19-NOV-23 02.48.47.000000 PM
field1,field2,field3,field4,field5,field6,19-NOV-23 10.58.03.000000 AM

c9qzyr3d

c9qzyr3d2#

Decorate-Sort-Undecorate习惯用法适用于任何awk、任何sort和任何cut:

$ awk -F',' -v OFS='\t' '{
    split($NF,t,/[- ]/)
    mthNr = (index("JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC",t[2])+2)/3
    printf "%02d%02d%02d%s%s\t%s\n", t[3], mthNr, t[1], t[5], t[4], $0
}' file.csv | sort -k1,1 | cut -f2-
field1,field2,field3,field4,field5,field6,19-NOV-23 10.58.03.000000 AM
field1,field2,field3,field4,field5,field6,19-NOV-23 02.48.47.000000 PM

字符串

$ awk -F',' -v OFS='\t' '{
    split($NF,t,/[- ]/)
    mthNr = (index("JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC",t[2])+2)/3
    printf "%02d%02d%02d%s%s\t%s\n", t[3], mthNr, t[1], t[5], t[4], $0
}' file.csv | sort -rk1,1 | cut -f2-
field1,field2,field3,field4,field5,field6,19-NOV-23 02.48.47.000000 PM
field1,field2,field3,field4,field5,field6,19-NOV-23 10.58.03.000000 AM


如果你不确定这是如何工作的,请查看awk命令的输出,该命令在cut(undecorates)再次删除它之前,将密钥时间戳添加到(装饰)sort的输入上:

231119AM10.58.03.000000 field1,field2,field3,field4,field5,field6,19-NOV-23 10.58.03.000000 AM
231119PM02.48.47.000000 field1,field2,field3,field4,field5,field6,19-NOV-23 02.48.47.000000 PM


注意它会按照所需的顺序进行排序。

相关问题