按列组排序并忽略此示例中失败的其他列,为什么?

Gil*_*les 4 text-processing sort

我无法弄清楚为什么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   
Run Code Online (Sandbox Code Playgroud)

这是我当前的输出:

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   
Run Code Online (Sandbox Code Playgroud)

但我想要的和预期的输出应该是:

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 
Run Code Online (Sandbox Code Playgroud)

我正在使用Linux。

Kus*_*nda 7

问题是您的排序键是包含逗号的字符串。

当比较其中两个键(如4,1700,2050,ART和 )时4,1600,2050,ART,它们比较相等,因为(在您的语言环境中)只有键的第一部分可以转换为数值(4 和 4)。

要解决此问题,请分别将每个字段与该字段的正确类型(数字或非数字)进行比较:

sort -s -t, -k3,3n -k4,4n -k5,5n -k6,6 file
Run Code Online (Sandbox Code Playgroud)

大多数实现都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
[...]
Run Code Online (Sandbox Code Playgroud)

cmp1=0表明键k1k2比较相等。

作为比较:

$ 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
[...]
Run Code Online (Sandbox Code Playgroud)

GNUsort可能会以完全不同的格式生成调试输出。