使用LC_COLLATE指定排序顺序,因此小写字母在大写字母之前


16

给定文件:

$ cat file
1
a
C
B
2
c
3
A
b

默认情况下sort

$ sort file
1
2
3
a
A
b
B
c
C

随着LC_COLLATE=C因此其排序在小写之前大写字母:

$ LC_COLLATE=C sort file
1
2
3
A
B
C
a
b
c

是否有可能获得排序以颠倒大小写顺序,即数字,小写然后大写?

Answers:


8

我不知道默认情况下按该顺序排序的任何语言环境。解决方案是使用自定义排序顺序创建自定义语言环境。四年后,如果有人想以自定义方式分类,这就是窍门。

绝大多数语言环境没有指定自己的排序顺序,而是复制定义的排序顺序,/usr/share/i18n/locales/iso14651_t1_common以便您进行编辑。iso14651_t1_common建议您制作一个副本,而不是通过修改原始语言来更改几乎每个语言环境的排序顺序。在类似问题的答案中,$HOME可以找到有关排序顺序的工作方式以及如何在没有root访问权限的情况下在目录中创建自定义语言环境的详细信息。

看一看如何根据它们在中的条目排序a和:Aiso14651_t1_common

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A

bB类似:

<U0062> <b>;<BAS>;<MIN>;IGNORE # 233 b
<U0042> <b>;<BAS>;<CAP>;IGNORE # 550 B

我们看到,在第一遍中,都有aA都有整理符号<a>,而都有bB都有整理符号<b>。从<a>出现在<b>iso14651_t1_commonaAb和之前并列B。第二遍不会破坏联系,因为所有四个字符都具有校对符号<BAS>,但是在第三遍期间,由于小写字母的校对符号<MIN>出现在第3467 <CAP>行(大写字母的校对符号之前)(第3488行),关系得到解决。因此,排序顺序结束了aAbB

交换第一个和第三个排序符号将首先按大小写字母(小写,然后是大写),然后按重音(<BAS>表示不带重音),然后按字母顺序排序。 但是<MIN><CAP>都在数字前面,因此这会对数字放在字母后面产生不良影响。

使所有小写字母优先于所有大写字母时,最先保持数字的最简单方法是通过将所有字母都设置为等于来强制所有字母在第一个比较中并列<a>。为确保它们在大小写上按字母顺序排序,请将最后一个排序规则符号从IGNORE更改为当前的第一个排序规则符号。遵循此模式,a将变为:

<U0061> <a>;<BAS>;<MIN>;<a> # 198 a

A 会成为:

<U0041> <a>;<BAS>;<CAP>;<a> # 517 A

b 会成为:

<U0062> <a>;<BAS>;<MIN>;<b> # 233 b

B 会成为:

<U0042> <a>;<BAS>;<CAP>;<b> # 550 B

其余的字母,依此类推。

创建的自定义版本后iso14651_t1_common,请按照上面链接的答案中的说明编译您的自定义语言环境。


6

设置LC_COLLATE=C并不总是足够在小写字母之前对大写字母排序。您可能需要设置LC_ALL=C

这还将考虑非字母数字甚至不可打印的字符,但是如果您不希望有选项,-d并且-i(请参见中的介绍man sort)将其关闭。

但是,对于多字节输入,它可能会严重失败,例如带有非ASCII字符的UTF-8。

为了使小写字母(按顺序)先于大写字母(按顺序),我能想到的最好方法不涉及分解一种成熟的编程语言,是将排序前的所有字母的大小写都取反,然后将它们取反然后。

tr 'a-zA-Z' 'A-Za-z' < file | LC_ALL=C sort | tr 'a-zA-Z' 'A-Za-z'

2

我不是专家,但是我从未见过像这样定义归类的语言环境。AFAIK仅在基于ASCII值的 C中使用此排序规则。(通常我只能通过脚本来解决。)

但是,我从来没有做过,但是您可能想要查看localedef(1)locale(5)联机帮助页,以了解如何定义语言环境并最终定义自己的语言环境。

同样不要忘记,如果有任何变音符号或特殊字符,C语言环境将不会像您想的那样对待它们。例如,它不会把á接近aŁ附近L。在这种情况下,该语言的本地语言环境可能是一个更好的起点。


0

我相信答案是无需更改LC_COLLATE(意味着将函数保留为默认行为):

排序-f文件

这在Linux上有效;如果您在Unix上并运行其他版本,请参阅命令的帮助部分。-f定义为忽略大小写。

感谢相当(且奇怪)的快速修复以及对错误放置的语法Stephen Rauch的编辑。


-1
LC_COLLATE="en_US.UTF-8" sort file

这不会在大写之前排序小写吗?ideone.com/Gtyg4Z
iiSeymour 2013年

嗯,在我的情况下,它确实使用您的示例。
unxnut

4
@unxnut这是不正确的。如果没有分号,该命令将为其设置环境sort,但使用分号时,该变量仅在shell内,不会影响的行为sort。如果还导出了变量,则可以保留分号,但是这也会影响其他命令。
AndersSjöqvist17年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.