5

How are following sort commands in unix different?

1) sort -k1,4 < file
2) sort -k1,1 -k4,4 < file
3) sort -k1,1 -k2,2 -k3,3 -k4,4 < file

Especially, #1 and #2 are confusing. For example, the following example illustrates my points

$ 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

And I did look at the sort's man page In sort's man page, it says:

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

But I don't understand this explanation. If it starts from POS1 and end it at POS2, then shouln't #1 and #3 commands above produce the same results?

4

1 回答 1

1

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

在您的第一种情况下,根据您的语言环境,您可以获得不同的结果(LC_ALL=C sort -k1,4 < file例如,尝试将其与 进行比较LC_ALL=en_US.utf8 sort -k1,4 < file)。

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

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

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

于 2013-06-04T21:44:49.070 回答