仅按第一个键排序(保留其余顺序)
sort with first key only (preserve order for rest)
我有一个文件,例如
day1 aargh
day2 boom
day3 crack
day2 argh
并且我想根据第一个键排序,而不是任何其他键,也就是说,我想保留顺序键相同的行数。
没想到会这么简单
$ sort -k1,1 myfile
day1 aargh
day2 aargh
day2 boom
day3 crack
但是哎呀。可以看到,sort 无缘无故把原来的第 4 行放在第 2 行之前,丢掉了原来的顺序。 (在第 2 天。"boom" 在 "aargh" 之前——而不是相反。没有 2 "aargh" 没有 "boom"!:))。
我想要的是:
$ sort -k1,1 myfile
day1 aargh
day2 boom
day2 aargh
day3 crack
这是为什么?那是一个错误吗?更重要的是,如何让排序按照我想要的方式进行?
您需要使用此选项:
-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,1
与没有选项的 sort
表现不同的例子,因为整行比较将从与第一个相同的字节开始-场比较。但是您肯定可以看出 sort -k2,2
具有不同的含义:首先尝试第二个字段,然后是整行。所以 -k1,1
本身就是一种无用的退化情况。
至于 为什么 ... sort
的默认行为至少可以追溯到版本 6 UNIX -看到 the man page from 1975 说
Lines that compare equal are ordered with all bytes significant.
(而且也没有 -s
选项来禁用它!)
sort
奇怪的默认行为只是我们不得不忍受的历史事件,因为旧的和广泛使用的东西不能更改其默认值。感谢 GNU 的 --debug
选项,这是一个相对较晚的添加,于 2010 年推出。
Wumpus 已经给出了正确答案。我试图将其添加为评论,但它太长了,所以请不要给我投低票:)
"A pair of lines is compared as follows: sort compares each pair of fields, in the order specified on the command line, according to the associated ordering options, until a difference is found or no fields are left. If no key fields are specified, sort uses a default key of the entire line. Finally, as a last resort when all keys compare equal, sort compares entire lines as if no ordering options other than --reverse (-r) were specified. The --stable (-s) option disables this last-resort comparison so that lines in which all fields compare equal are left in their original relative order. The --unique (-u) option also disables the last-resort comparison."
sort-invocation
我有一个文件,例如
day1 aargh
day2 boom
day3 crack
day2 argh
并且我想根据第一个键排序,而不是任何其他键,也就是说,我想保留顺序键相同的行数。
没想到会这么简单
$ sort -k1,1 myfile
day1 aargh
day2 aargh
day2 boom
day3 crack
但是哎呀。可以看到,sort 无缘无故把原来的第 4 行放在第 2 行之前,丢掉了原来的顺序。 (在第 2 天。"boom" 在 "aargh" 之前——而不是相反。没有 2 "aargh" 没有 "boom"!:))。
我想要的是:
$ sort -k1,1 myfile
day1 aargh
day2 boom
day2 aargh
day3 crack
这是为什么?那是一个错误吗?更重要的是,如何让排序按照我想要的方式进行?
您需要使用此选项:
-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,1
与没有选项的 sort
表现不同的例子,因为整行比较将从与第一个相同的字节开始-场比较。但是您肯定可以看出 sort -k2,2
具有不同的含义:首先尝试第二个字段,然后是整行。所以 -k1,1
本身就是一种无用的退化情况。
至于 为什么 ... sort
的默认行为至少可以追溯到版本 6 UNIX -看到 the man page from 1975 说
Lines that compare equal are ordered with all bytes significant.
(而且也没有 -s
选项来禁用它!)
sort
奇怪的默认行为只是我们不得不忍受的历史事件,因为旧的和广泛使用的东西不能更改其默认值。感谢 GNU 的 --debug
选项,这是一个相对较晚的添加,于 2010 年推出。
Wumpus 已经给出了正确答案。我试图将其添加为评论,但它太长了,所以请不要给我投低票:)
"A pair of lines is compared as follows: sort compares each pair of fields, in the order specified on the command line, according to the associated ordering options, until a difference is found or no fields are left. If no key fields are specified, sort uses a default key of the entire line. Finally, as a last resort when all keys compare equal, sort compares entire lines as if no ordering options other than --reverse (-r) were specified. The --stable (-s) option disables this last-resort comparison so that lines in which all fields compare equal are left in their original relative order. The --unique (-u) option also disables the last-resort comparison." sort-invocation