为什么 ls 排序会忽略非字母数字字符?

dan*_*ann 29 ls sort

排序文件名时,ls忽略-,_. 我希望它也能在排序中使用这些字符。

一个例子:

touch a1 a2 a-1 a-2 a_1 a_2 a.1 a.2 a,1 a,2
Run Code Online (Sandbox Code Playgroud)

现在显示这些文件ls -1

a1
a_1
a-1
a,1
a.1
a2
a_2
a-2
a,2
a.2
Run Code Online (Sandbox Code Playgroud)

我期望的是这样的:

a1
a2
a,1
a,2
a.1
a.2
a_1
a_2
a-1
a-2
Run Code Online (Sandbox Code Playgroud)

即我希望在排序时考虑非字母数字字符。

谁能解释这种行为?这种行为是由标准强制要求的吗?或者这是因为编码是UTF-8?

更新:这似乎与 UTF-8 排序有关:

$ LC_COLLATE=C ls -1
a,1
a,2
a-1
a-2
a.1
a.2
a1
a2
a_1
a_2
Run Code Online (Sandbox Code Playgroud)

Pet*_*r.O 13

编辑:添加了对使用 LC_COLLATE=C 排序的数据的测试


默认的整理序列将那些“标点类型”字符视为具有相同的值......Use LC_COLLATE=C以代码点顺序对待它们......

for i in 'a1' 'a_1' 'a-1' 'a,1' 'a.1' 'a2' 'a_2' 'a-2' 'a,2' 'a.2' ;do
  echo $i; 
done |LC_COLLATE=C sort
Run Code Online (Sandbox Code Playgroud)

输出

a,1
a,2
a-1
a-2
a.1
a.2
a1
a2
a_1
a_2
Run Code Online (Sandbox Code Playgroud)

以下代码测试基本多语言平面中的所有有效UTF-8 字符(除了\x00\x0a;为简单起见)
它将已知(生成)升序序列中的文件与随机排序的文件进行比较,然后再次排序LC_COLLATE=C。结果表明,C序列与原始生成的序列相同。

{ i=0 j=0 k=0 l=0
  for i in {0..9} {A..F} ;do
  for j in {0..9} {A..F} ;do
  for k in {0..9} {A..F} ;do
  for l in {0..9} {A..F} ;do
     (( 16#$i$j$k$l == 16#0000 )) && { printf '.' >&2; continue; }
     (( 16#$i$j$k$l == 16#000A )) && { printf '.' >&2; continue; }
     (( 16#$i$j$k$l >= 16#D800    && 
        16#$i$j$k$l <= 16#DFFF )) && { printf '.' >&2; continue; }
     (( 16#$i$j$k$l >= 16#FFFE )) && { printf '.' >&2; continue; }
     echo 0x"$i$j$k$l" |recode UTF-16BE/x4..UTF-8 || { echo "ERROR at codepoint $i$j$k$l " >&2; continue; } 
     echo 
  done
  done
  done; echo -n "$i$j$k$l " >&2
  done; echo >&2
} >listGen

             sort -R listGen    > listRandom
LC_COLLATE=C sort    listRandom > listCsort 

diff <(cat listGen;   echo "last line of listOrig " ) \
     <(cat listCsort; echo "last line of listCsort" )
echo 
cmp listGen listCsort; echo 'cmp $?='$?
Run Code Online (Sandbox Code Playgroud)

输出:

63485c63485
< last line of listOrig 
---
> last line of listCsort

cmp $?=0
Run Code Online (Sandbox Code Playgroud)

  • 这是在哪里记录的?那是 Unicode 标准的一部分吗? (2认同)
  • 实际上,它们没有得到相同的值;这些字符在排序时会被忽略。如果它们被视为具有相等的值,则排序顺序 `a_1 a2 a_2` 将是不可能的。 (2认同)

Ign*_*ams 11

这与字符集无关。相反,语言决定了整理顺序。libc中检查该语言显示$LC_COLLATE/ $LC_ALL/$LANG并查找其归类规则(如/usr/share/i18n/locales/*为执导的glibc)和订单的文本。