lsソートが英数字以外の文字を無視するのはなぜですか?

lsソートが英数字以外の文字を無視するのはなぜですか?

ファイル名のソート時にls無視します-,_。ソート時にもこの文字を使いたいです。

一例:

touch a1 a2 a-1 a-2 a_1 a_2 a.1 a.2 a,1 a,2

次に、次のファイルを表示しますls -1

a1
a_1
a-1
a,1
a.1
a2
a_2
a-2
a,2
a.2

私が期待するのはこれです:

a1
a2
a,1
a,2
a.1
a.2
a_1
a_2
a-1
a-2

つまり、ソート時に英数字以外の文字を考慮したいのです。

誰でもこの動作を説明できますか?この動作は標準によって実施されますか?それともエンコーディングが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

答え1

編集: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

出力

a,1
a,2
a-1
a-2
a.1
a.2
a1
a2
a_1
a_2

次のコードはすべてテストします。効果的な基本多言語平面のUTF-8文字(例外\x00そして\x0a;簡略化のために、既知の
(生成された)昇順のファイルをランダムにソートされたファイルと比較し、LC_COLLATE = 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 $?='$?

出力:

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

cmp $?=0

答え2

これは文字セットとは関係ありません。代わりに、順序ルールを決定するのは言語です。 libcは$LC_COLLATE//$LC_ALLに表示されている言語を確認し、$LANGその組み合わせ(GLibCなど)を見つけて、指示に従って/usr/share/i18n/locales/*テキストをソートします。

答え3

私はDebianのデフォルトのソートオプションとまったく同じ問題を抱えていましたが、私はコンマを無視してCSVデータを効率的にソートするのを防ぎ、AIに大きなダメージを与えました。

解決策は、sortソートを単独で使用するのではなく、ソートがデフォルトの動作として表示されるように強制する必要があることです-d, --dictionary-order

実行コマンド:

sort -V

私の問題を解決し、コンマを検討してください。

答え4

ただコメントです... アクセントのため 'C'を使用できないため、私の照合順序(es_AR.utf8)に大きな問題があります。そして最も悪いことは、問題がデータベースpostgresqlにも存在することです。 10 '10'と '10.1'の間の文に含める(例) '100'の値を期待していません。すべてのクエリで照合を使用する必要があるようです。 '' は true を表示しますが、 SELECT '100' BETWEEN '10' AND '10.Z' COLLATE "C" は正しい 'false' を表示します (私の考えでは)。

関連情報