![按列组排序并忽略此示例中失败的其他列,为什么?](https://linux22.com/image/211932/%E6%8C%89%E5%88%97%E7%BB%84%E6%8E%92%E5%BA%8F%E5%B9%B6%E5%BF%BD%E7%95%A5%E6%AD%A4%E7%A4%BA%E4%BE%8B%E4%B8%AD%E5%A4%B1%E8%B4%A5%E7%9A%84%E5%85%B6%E4%BB%96%E5%88%97%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%EF%BC%9F.png)
我无法弄清楚为什么sort
不能正常工作,但它是根据我告诉它不要这样做的列进行排序的。我想先按第 3 列按优先级排序,然后按第 4 列、第 5 列、第 6 列进行排序。这是怎么回事?
这是我的代码:sort -n -s -t ',' -k3,6
这是我的输入:
a1,b1,2,15,50,ABBA
a1,a1,2,26,55,ABBA
a11,2a1,2,33,55,ABBA
b1,a1,2,80,99,ABA
c2,a1,3,20,40,CAN
a1,b2,3,51,300,CAN
a3,a3,4,1000,2000,ART
d3,c3,4,1700,2050,ART
d3,c2c,4,1600,2050,ART
b1,a3,4,1800,2051,ART
这是我当前的输出:
a1,b1,2,15,50,ABBA
a1,a1,2,26,55,ABBA
a11,2a1,2,33,55,ABBA
b1,a1,2,80,99,ABA
c2,a1,3,20,40,CAN
a1,b2,3,51,300,CAN
a3,a3,4,1000,2000,ART
d3,c3,4,1700,2050,ART
d3,c2c,4,1600,2050,ART
b1,a3,4,1800,2051,ART
但我想要的和预期的输出应该是:
a1,b1,2,15,50,ABBA
a1,a1,2,26,55,ABBA
a11,2a1,2,33,55,ABBA
b1,a1,2,80,99,ABA
c2,a1,3,20,40,CAN
a1,b2,3,51,300,CAN
a3,a3,4,1000,2000,ART
d3,c2c,4,1600,2050,ART
d3,c3,4,1700,2050,ART
b1,a3,4,1800,2051,ART
我正在使用Linux。
答案1
问题是您的排序键是包含逗号的字符串。
当比较其中两个键时,例如4,1700,2050,ART
和4,1600,2050,ART
,它们比较平等的因为(在您的语言环境中)只有键的第一部分可以转换为数值(4 和 4)。
要解决此问题,请分别将每个字段与该字段的正确类型(数字或非数字)进行比较:
sort -s -t, -k3,3n -k4,4n -k5,5n -k6,6 file
大多数实现都sort
提供了一个--debug
对于检测此类问题非常有帮助的选项。在我的 FreeBSD 系统上,这清楚地表明您的原始命令在比较我提到的字段时存在问题:
$ sort --debug -n -s -t ',' -k3,6 file
[...]
; k1=<4,1000,2000,ART >, k2=<4,1700,2050,ART >; s1=<a3,a3,4,1000,2000,ART >, s2=<d3,c3,4,1700,2050,ART >; cmp1=0
; k1=<4,1700,2050,ART >, k2=<4,1600,2050,ART >; s1=<d3,c3,4,1700,2050,ART >, s2=<d3,c2c,4,1600,2050,ART >; cmp1=0
; k1=<4,1600,2050,ART >, k2=<4,1800,2051,ART >; s1=<d3,c2c,4,1600,2050,ART >, s2=<b1,a3,4,1800,2051,ART >; cmp1=0
[...]
cmp1=0
表明键k1
和k2
比较相等。
作为比较:
$ sort --debug -s -t, -k3,3n -k4,4n -k5,5n -k6,6 file
[...]
; k1=<4>, k2=<4>; k1=<1000>, k2=<1700>; s1=<a3,a3,4,1000,2000,ART >, s2=<d3,c3,4,1700,2050,ART >; cmp1=-1
; k1=<4>, k2=<4>; k1=<1700>, k2=<1600>; s1=<d3,c3,4,1700,2050,ART >, s2=<d3,c2c,4,1600,2050,ART >; cmp1=1
; k1=<4>, k2=<4>; k1=<1000>, k2=<1600>; s1=<a3,a3,4,1000,2000,ART >, s2=<d3,c2c,4,1600,2050,ART >; cmp1=-1
; k1=<4>, k2=<4>; k1=<1700>, k2=<1800>; s1=<d3,c3,4,1700,2050,ART >, s2=<b1,a3,4,1800,2051,ART >; cmp1=-1
[...]
GNUsort
可能会以完全不同的格式生成调试输出。
答案2
问题在于您是按词汇排序而不是按数字排序。您需要-n
按数字排序,否则100
将在123
甚至之前排序2
:
$ printf '2\n123\n100\n' | sort
100
123
2
但是,随着-n
:
$ printf '2\n123\n100\n' | sort -n
2
100
123
因此,在您的情况下,您需要将 添加到n
要按数字排序的字段:
$ sort -t, -k3n,6n file
a1,b1,2,15,50,ABBA
a1,a1,2,26,55,ABBA
a11,2a1,2,33,55,ABBA
b1,a1,2,80,99,ABA
c2,a1,3,20,40,CAN
a1,b2,3,51,300,CAN
a3,a3,4,1000,2000,ART
d3,c2c,4,1600,2050,ART
d3,c3,4,1700,2050,ART
b1,a3,4,1800,2051,ART