ファイル名のソート時に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