仅使用第一个键排序(保留休息顺序)

时间:2015-05-06 15:44:41

标签: sorting unix gnu-coreutils

我有一个文件,如

day1 aargh
day2 boom
day3 crack
day2 argh

我希望根据第一个键对其进行排序,但不是任何其他键,也就是说,我想保留键的相同行的顺序

我想到它会像

一样简单
$ sort -k1,1 myfile
day1 aargh
day2 aargh
day2 boom
day3 crack

但是哎呀。正如您所看到的, sort 将原始行4放在第2行之前,没有任何理由,丢弃原始订单。 (在第2天。"繁荣"之前" aargh" - 不是其他方式。没有2" aargh" s没有"繁荣&# 34;!:))。

我想要的是:

$ sort -k1,1 myfile
day1 aargh
day2 boom
day2 aargh
day3 crack

为什么?那是一个错误吗?更重要的是,如何使排序行为符合我的要求?

2 个答案:

答案 0 :(得分:2)

您需要使用此选项:

-s, --stable
       stabilize sort by disabling last-resort comparison

最后一次比较是整行的逐字比较,如果所有键都相等则使用。

下次你遇到sort时遇到问题(如果继续使用它肯定会遇到更多麻烦;其中有很多不直观的事情)尝试使用--debug看看是什么正在进行比较。

如果你只是这一行:

day2 aargh

并尝试sort --debug -k1,1就可以了:

day2 aargh
____
__________

输入行在day2下显示一行下划线。这意味着day2是该行的最高优先级排序键。它将与其他行的最高优先级排序键进行比较,以确定哪一个排在第一位。由于-k1,1

,此密钥包含在密钥列表中

下一行下划线在整行之下。这意味着按降序优先级顺序排列的下一个排序键是整行。如果-k1,1键在一对行中完全相同,则接下来将对此进行比较。由于缺少-s

,此密钥包含在密钥列表中

使用-s -k1,1 --debug再次尝试,然后您会看到第二行下划线消失。

我无法想到sort -k1,1sort的行为不同而没有选项的示例,因为整行比较将以与第一个相同的字节开始 - 现场比较。但肯定你可以看到sort -k2,2有一个明显的含义:首先尝试第二个字段,然后是整行。所以-k1,1本身就是一种无用的退化案例。

至于为什么 ... sort的默认行为包括至少早于第6版UNIX的最后一次整行比较 - 请参阅{{3} }说

  

比较相等的行按所有字节显着排序。

(并且没有-s选项来禁用它!)

sort的奇怪默认行为只是我们必须忍受的历史事物,因为旧的和广泛使用的东西不能更改其默认值。要感谢GNU的--debug选项,这是2010年推出的相对较晚的选项。

答案 1 :(得分:1)

Wumpus已经提供了正确的答案。我试图将此添加为评论,但它太长了,所以,请不要低估我:)

  

"按如下方式比较一对行:sort按照命令行中指定的顺序,根据相关的排序选项比较每对字段,直到找到差异或没有剩余字段。如果未指定任何键字段,则sort将使用整行的默认键。最后,作为最后的手段,当所有键比较相等时,sort会比较整行,就像没有指定除--reverse(-r)之外的任何排序选项一样。 --stable(-s)选项禁用此最后的比较,以便所有字段比较相等的行保留其原始相对顺序。 --unique(-u)选项也会禁用最后的比较。"   sort-invocation