小文字が大文字の前になるように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

大文字と小文字の順序、つまり数字、小文字、大文字を逆順に並べ替えることは可能ですか?

回答:


8

デフォルトでその順序でソートされるロケールは知りません。解決策は、カスタマイズされたソート順でカスタムロケールを作成することです。4年後、だれかがカスタムの方法で並べ替えたいと思うなら、ここにトリックがあります。

大部分のロケールは独自のソート順を指定せず、代わりに定義されたソート順をコピーする/usr/share/i18n/locales/iso14651_t1_commonので、編集する必要があります。オリジナルを変更してほぼすべてのロケールのソート順を変更するのではなくiso14651_t1_common、コピーを作成することをお勧めします。ソート順のしくみと$HOMEルートアクセスなしでディレクトリにカスタムロケールを作成する方法の詳細は、同様の質問に対するこの回答に記載されています

以下のエントリに基づいてどのように順序付けされているかaを見てください。Aiso14651_t1_common

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

bそして、B類似しています。

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

私たちは、最初のパスでそれを参照してください、両方aA照合シンボルを持って<a>、両方の間、bおよびB照合シンボルを持っています<b>。以来<a>現れ前<b>iso14651_t1_commonaそしてA前に結びついているbB。4つのすべての文字が照合シンボルを持っているので、第2のパスがつながりを破壊しない<BAS>小文字のための照合シンボルがあるため、しかし、第3のパスの間に絆が解決されている<MIN>大文字のための照合シンボルの前に、行3467に表示されます<CAP>(ライン3488) 。だから、ソート順序は、として終わりますaAbB

1番目と3番目の照合記号を交換すると、最初に大文字(小文字、次に大文字)、次にアクセント(アクセント記号なし<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

私は専門家ではありませんが、このような照合を定義するロケールを見たことはありません。私の知る限り、この照合はASCII値に基づいているCのみです。(通常、スクリプトでこれを解決するだけです。)

ただし、これを行ったことはありませんが、localedef(1)およびlocale(5)のマンページを見て、ロケールの定義方法を理解し、最終的にロケールを定義することをお勧めします。

また、発音区別符号または特殊文字がある場合、Cロケールはそれらを必要に応じて処理しないことを忘れないでください。たとえば、á近くにaŁ近くにも配置されませんL。そのような場合、おそらく言語のネイティブロケールがより良い出発点になるでしょう。


0

LC_COLLATEを変更する必要はありません(関数をデフォルトの動作のままにすることを意味します)。

sort -fファイル

これはLinuxで機能します。Unixで別のバージョンを実行している場合は、コマンドのヘルプセクションを参照してください。-fは、大文字と小文字を区別しないと定義されています。

見当違いの文法、Stephen Rauchのかなり(および奇妙な)迅速な修正と編集に感謝します。


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

これは小文字を大文字の前にソートしませんか?ideone.com/Gtyg4Z
iiSeymour

うーん、私の場合、あなたの例を使ってやった。
unxnut

4
@unxnutこれは間違っています。セミコロンを使用しない場合、コマンドはの環境を設定しますsortが、セミコロンを使用すると、変数はシェルに対してローカルであり、の動作に影響しませんsort。変数もエクスポートされる場合、セミコロンはそのまま保持できますが、他のコマンドにも影響します。
アンデルスシェークヴィスト
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.