unix中的以下排序命令有何不同?
1) sort -k1,4 < file
2) sort -k1,1 -k4,4 < file
3) sort -k1,1 -k2,2 -k3,3 -k4,4 < file
特别是,#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
我确实查看了排序的手册页 在sort的手册页中,它说:
-k, --key=POS1[,POS2]
start a key at POS1 (origin 1), end it at POS2 (default end of line)
但我不明白这个解释。如果它从POS1开始并在POS2结束,那么上面的#1和#3命令是否会产生相同的结果?
答案 0 :(得分:2)
不同之处在于#1将整行视为单个键,并按字典顺序对其进行排序。另外两个键有多个键,特别是#3使用与#1相同的字段集时,它以非常不同的方式使用。它首先按第一列对列表进行排序(空白属于跟随字段,除非您指定-b
,否则是重要的),如果两行或多行具有相同的行,则为第一列中的值,然后它使用第二个键对行的子集进行排序。如果前两列中两行或多行相同,则使用第三个键等
在第一种情况下,根据您的语言环境,您可以获得不同的结果(尝试LC_ALL=C sort -k1,4 < file
并将其与例如LC_ALL=en_US.utf8 sort -k1,4 < file
进行比较)。
在第二种情况和第三种情况下,由于在从非空白到空白的过渡中分割键。这意味着第2列和后续列具有不同大小的空白前缀,这会影响排序顺序,因为您未指定-b
。
另外,如果你有混合的空格和标签来排列你的列,那可能会弄乱你的东西。
当我在我的环境中LC_ALL=en_US.utf8
时,我得到了相同的结果,但使用LC_ALL=C
(SuSE Enterprise 11.2)获得了预期的结果(即没有差异)。