当排序不知道排序顺序时,GNU 排序稳定排序

当排序不知道排序顺序时,GNU 排序稳定排序

我有一个两列的文件;该文件已按照我想要的方式在第 1 列中排序。我想对第 1 列每个类别中的第 2 列进行排序。但是,sort不理解第 1 列的排序顺序。

正常的方法(来自堆栈上的类似问题)是这样的:

sort --stable -k1,1 -k2,2n

但我无法指定 k1 的排序,因为它是任意的。

输入示例:

C 2
C 1
A 2
A 1
B 2 
B 1

和输出:

C 1
C 2
A 1
A 2
B 1 
B 2

答案1

您可以使用 awk 为每个块开始新的排序:

% awk -v cmd="sort -k2,2" '$1 != prev {close(cmd); prev=$1} {print | cmd}' foo
C 1
C 2
A 1
A 2
B 1
B 2
  • $1 != prev {close(cmd); prev=$1}- 当保存的值不同时,我们有一个新的块,因此我们关闭任何先前启动的块sort
  • {print | "sort -k2,2"}'将输出通过管道传输到sort,如果它尚未运行则启动它(awk 可以跟踪它启动的命令)

答案2

你可以使用施瓦茨变换(这基本上是您在评论中提到的装饰-排序-不装饰方法,但可能比穆鲁的 很好的答案由于使用单个sort调用而不是多个) - 使用awk添加前缀列,该前缀列随着第一列中值的变化而递增,按前缀列排序接下来是“第二”列(由于前缀列的存在,其序数位置暂时转移到3),最后去掉前缀列

awk '{print ($1 in a? c+0: ++c)"\t" $0; a[$1]}' file | sort -k1,1n  -k3,3 | cut -f 2-

相关内容