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

iiS*_*our 21 linux sort

鉴于文件:

$ cat file
1
a
C
B
2
c
3
A
b
Run Code Online (Sandbox Code Playgroud)

默认情况下sort将:

$ sort file
1
2
3
a
A
b
B
c
C
Run Code Online (Sandbox Code Playgroud)

使用LC_COLLATE=Cso 将在小写之前按大写字母排序:

$ LC_COLLATE=C sort file
1
2
3
A
B
C
a
b
c
Run Code Online (Sandbox Code Playgroud)

是否可以通过排序来反转大小写顺序,即数字,小写然后大写?

bea*_*dip 13

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

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

看看如何aA根据他们在 中的条目排序iso14651_t1_common

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A
Run Code Online (Sandbox Code Playgroud)

b并且B是相似的:

<U0062> <b>;<BAS>;<MIN>;IGNORE # 233 b
<U0042> <b>;<BAS>;<CAP>;IGNORE # 550 B
Run Code Online (Sandbox Code Playgroud)

我们看到,在第一遍中,aA都有校对符号<a>,而bB都有校对符号<b>。由于<a>出现之前<b>iso14651_t1_commonaA被捆绑之前bB。第二遍没有打破平局,因为所有四个字符都有整理符号<BAS>,但在第三遍中,平局得到解决,因为小写字母的整理符号<MIN>出现在第 3467 行,在大写字母的整理符号之前<CAP>(第 3488 行) . 所以排序顺序最终为a, A, b, B

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

所有小写字母排在所有大写字母之前的同时保留数字的最简单方法是通过将所有字母设置为等于 来强制所有字母在第一次比较期间并列<a>。为确保它们在大小写中按字母顺序排序,请将最后一个整理符号从IGNORE更改为当前第一个整理符号。按照这个模式,a将变成:

<U0061> <a>;<BAS>;<MIN>;<a> # 198 a
Run Code Online (Sandbox Code Playgroud)

A 会成为:

<U0041> <a>;<BAS>;<CAP>;<a> # 517 A
Run Code Online (Sandbox Code Playgroud)

b 会成为:

<U0062> <a>;<BAS>;<MIN>;<b> # 233 b
Run Code Online (Sandbox Code Playgroud)

B 会成为:

<U0042> <a>;<BAS>;<CAP>;<b> # 550 B
Run Code Online (Sandbox Code Playgroud)

其余的字母依此类推。

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


Law*_*w29 7

设置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'
Run Code Online (Sandbox Code Playgroud)