我有很多类似下面的列表,第一列是ID号,第二列是分数,第三列是出生日期,格式为DDMMYYYY。
111 100 01012011
222 90 01012001
333 90 01012013
444 80 01012015
555 80 01012014
666 70 01012016
777 60 01012017
888 50 01012018
当有多个行具有相同的分数时,我希望将它们重新排序,最新的日期位于顶部,示例的结果将是:
111 100 01012011
333 90 01012013
222 90 01012001
555 80 01012014
444 80 01012015
666 70 01012016
777 60 01012017
888 50 01012018
如您所见,分数相同的行已重新排列,最新日期位于顶部。
我首先尝试选择最早的日期,我可以用以下方法来完成:
sort -k1.5 -k1.1,1.2 -k1.3,1.4 | tail -n 1
但是我不确定我怎样才能达到这个结果。我怎样才能达到这个结果?
7条答案
按热度按时间4ioopgfo1#
当前
sort
尝试的问题是,当您想要解析第三个字段(-k3.
)时,您正在尝试解析第一个字段(-k1.
)。设置,添加一些日期不是
DDMM == 0101
的条目:一种方法,假设第一次排序是针对第二个字段(
score
),以递减数字顺序进行:其中:
-t ' '
-将分隔符定义为空格(覆盖默认值,即非空白到空白的转换,这将导致前导空格被计为字段的一部分)-k2,2nr
-第一次排序(score
),以字段2
开始,以字段2
结束,按n
数字和r
反向(即降序)顺序排序-k3.5,3.8nr
-第二次排序(YYYY
),以字段3
和第5
个字符开始,以字段3
和第8
个字符结束,按n
数值排序,并按r
相反顺序排序(-k3.3,3.4nr
和-k3.1,3.2nr
分别在MM
和DD
上执行r
与n
相反的数值排序)***注意:**OP的预期输出显示
ID=555
(YYYY=2014
)列在ID=444
(YYYY=2015
)之前;我假设这是一个打字错误,应该先列出ID=444
把艾德Morton的评论放到这个答案里...
-b
放弃所有前导空格(即替换-t ' '
),但...-b
选项;或者...-b
选项就可以当做全域旗标套用(索引键层级旗标会优先于全域层级旗标,并且会否定全域层级旗标)应用这些规则,我们得到以下结果之一:
这些都产生:
2vuwiymt2#
使用以下强制POSIX工具的任何版本进行修饰-排序-取消修饰:
我假设第二列
80
的过帐预期输出顺序为:是错误的。
pxiryf3j3#
使用Perl
获取整个文件(通过
-0777
开关),然后将其拆分为行,并将其输入Schwartzian变换(decorate-sort-undecorate),在此过程中反转日期格式--[]
),但首先将日期"反转"为yyyymmdd格式,以便以后可以方便地对其进行排序我假设在结束日期需要在ddmmyyyy格式,否则调整。
或者,从概念上来说,首先准备--读取所有行并使用单词列表的数组引用构建一个数组--然后对其进行排序可能更简单
其中
}{ ...
语法开始END
块,相当于END { ... }
。所有END
块在程序中的所有处理完成之后运行(参见perlmod);所以这里是在所有行都被读取之后。这里我还使用sprintf
对齐输出。对于Linux上的上述问题,使用系统的
sort
的解决方案显然要简单得多。当有其他原因需要引入编程语言时(即有更多工作要做),或者如果操作系统没有工具从命令行(Windows)执行此操作时,这里的方法可能会很有用。这不需要任何系统工具,而且它是高效的,因为它在排序之前预处理日期时间一次(并且在排序期间不为每个比较解析它们)。
注意:问题中的
444
和555
行对(80
在第二列)排序错误--应该是先有444
的行,然后是有555
的行,而不是相反,如图所示(根据问题描述:"* 最新日期在顶部 *")plupiseo4#
咱家呆呆:
ID SCORE YYYYMMDD
)排列。sort
。-k
标志指定为sort
将按这些字段排序,排序顺序为标志指定的顺序(即先按字段2排序,再按字段3排序)。-n
=数值排序,-r
=逆序(高-低),-t
=字段分隔符(空格)。如果你可以得到/使用
ID SCORE YYYYMMDD
的输入格式,你可以用同样的排序命令(没有gawk)简单地排序它。编辑:如果你想让分数高-低,日期低-高(旧-新),即不同的顺序,你可以用
sort -t ' ' -k 2,2rn -k 3,3n
代替上面的sort命令。sort
可以为每个键指定不同的标志。hzbexzde5#
这在我的MacOS终端上工作。
说明:我首先将日期格式转换为YYMMDD,然后进行排序。
olqngx596#
安装程序添加了一些日期不是
DDMM == 0101
的条目,添加了一些具有重复$2/$3
对的行:**注意:**文件中包含注解
一个
GNU awk
创意:备注:
PROCINFO["sorted_in"]
支持需要GNU awk
$2/$3
对的情况下,我们选择保持输入顺序;这可以根据OP关于如何在这种情况下继续进行的额外输入进行修改(例如,通过$1
进一步排序?删除重复行?)这会产生:
mkshixfv7#