unix中以下三个排序命令有什么区别?

Alb*_*lby 5 unix sorting

unix中的以下排序命令有何不同?

1) sort -k1,4 < file
2) sort -k1,1 -k4,4 < file
3) sort -k1,1 -k2,2 -k3,3 -k4,4 < file
Run Code Online (Sandbox Code Playgroud)

特别是,#1和#2令人困惑.例如,以下示例说明了我的观点

$ cat tmp
1       2       3       t
4       2       4       c
5       4       6       c
7       3       20      r
12      3       5       i
2       45      7       a
11      23      53      b
23      43      53      q
11      6       3       c
0       4       3       z

$ diff <(sort -k1,4 tmp) <(sort -k1,1 -k2,2 -k3,3 -k4,4 tmp)
1a2
> 1     2       3       t
5,6d5
< 1     2       3       t
< 23    43      53      q
7a7
> 23    43      53      q

$diff <(sort -k1,4 tmp) <(sort -k1,1 -k4,4 tmp)
1a2
> 1     2       3       t
5,6d5
< 1     2       3       t
< 23    43      53      q
7a7
> 23    43      53      q
Run Code Online (Sandbox Code Playgroud)

我确实查看了sort的手册页在sort的手册页中,它说:

-k, --key=POS1[,POS2]
 start a key at POS1 (origin 1), end it at POS2 (default end of line)
Run Code Online (Sandbox Code Playgroud)

但我不明白这个解释.如果它从POS1开始并在POS2结束,那么上面的#1和#3命令是否会产生相同的结果?

twa*_*erg 1

不同之处在于#1 将整行视为单个键,并按字典顺序对其进行排序。另外两个有多个键,特别是,虽然 #3 使用与 #1 相同的字段集,但它的方式却非常不同。它首先按第一列对列表进行排序(空格属于以下字段,并且很重要,除非您指定-b),并且如果两行或多行在第一列中具有相同的值,则它使用第二个键对其进行排序行的子集。如果两行或多行的前两列相同,则使用第三个键,依此类推。

在第一种情况下,根据您的区域设置,您可能会得到不同的结果(尝试LC_ALL=C sort -k1,4 < file将其与例如 进行比较LC_ALL=en_US.utf8 sort -k1,4 < file)。

在第二种和第三种情况下,因为键在从非空白到空白的转换上被分割。这意味着第二列和后续列具有不同大小的空白前缀,这会影响排序顺序,因为您没有指定-b

另外,如果您混合使用空格和制表符来排列列,这可能会造成混乱。

当我LC_ALL=en_US.utf8在我的环境中时,我得到了与您相同的结果,但是使用(SuSE Enterprise 11.2)得到了您的预期结果(即没有差异)LC_ALL=C