web-dev-qa-db-ja.com

LC_COLLATEでソート順を指定して、小文字が大文字の前になるようにします

ファイルを考えると:

$ 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

大文字と小文字の順序を逆にするソートを取得することは可能ですか?

17
iiSeymour

デフォルトでは、この順序でソートされるロケールは知りません。解決策は、カスタマイズされたソート順でカスタムロケールを作成することです。 4年後、だれかがカスタムの方法で並べ替えたい場合は、ここがコツです。

ほとんどのロケールは独自の並べ替え順序を指定していませんが、/usr/share/i18n/locales/iso14651_t1_commonで定義された並べ替え順序をコピーするので、これを編集します。元のiso14651_t1_commonを変更してほぼすべてのロケールのソート順を変更するのではなく、コピーを作成することをお勧めします。ソート順の仕組みと、ルートアクセスなしで$HOMEディレクトリにカスタムロケールを作成する方法の詳細は、次のように表示されます 同様の質問に対するこの回答

aAiso14651_t1_commonのエントリに基づいてどのように並べられているかを見てみましょう。

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

bBは似ています:

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

最初のパスでは、aAの両方に照合記号<a>があり、bBの両方に照合記号があることがわかりますシンボル<b><a><b>iso14651_t1_commonの前にあるので、aAbBの前に結合されます。 4番目の文字すべてに照合記号<BAS>があるため、2番目のパスはタイを壊しませんが、3番目のパスの間、小文字<MIN>の照合シンボルが3467行目にあるため、タイは解決されます。大文字の照合記号<CAP>(3488行目)。したがって、ソート順はaAbBになります。

最初と3番目の照合記号を入れ替えると、文字は最初に大文字(小文字、次に大文字)、次にアクセント(<BAS>はアクセントなしを意味します)、次にアルファベット順にソートされます。 ただし<MIN><CAP>の両方が数字の前にあるため、文字の後に数字を置くという望ましくない影響があります。 。

all小文字を前にall大文字にする前に数字を最初に保持する最も簡単な方法は、すべての文字を強制的に結合することですそれらをすべて<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のカスタマイズバージョンを作成したら、 上記のリンクされた回答 の手順に従って、カスタムロケールをコンパイルします。

9
beandip

LC_COLLATE=Cを設定しても、大文字を小文字の前にソートするのに必ずしも十分ではありません。 LC_ALL=Cの設定が必要になる場合があります。

これは英数字以外の文字や印刷できない文字も考慮しますが、それを望まない場合は、オプション-d-iman sortで説明)が有効になります。オフ。

ただし、ASCII以外の文字を含むUTF-8などのマルチバイト入力では、おそらく失敗します。

大文字(順番に)の前に小文字(順番に)を取得するには、本格的なプログラミング言語を作成することを含まないと考えることができる最良の方法は、並べ替え前にすべての文字の大文字と小文字を逆にし、それらを元に戻すことですその後。

tr 'a-zA-Z' 'A-Za-z' < file | LC_ALL=C sort | tr 'a-zA-Z' 'A-Za-z'
6
Law29

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

ただし、これを行ったことはありませんが、ロケールがどのように定義されているかを理解し、最終的には localedef(1) および locale(5) のマンページを確認することをお勧めします自分のもの。

また、分音記号や特殊文字がある場合、Cロケールではそれらが適切に処理されないことを忘れないでください。たとえば、áa付近またはŁL付近。そのような場合、言語のネイティブロケールがおそらくより良い開始点になります。

2
Alois Mahdal
LC_COLLATE="en_US.UTF-8"; sort file
0
unxnut

答えはLC_COLLATEを変更する必要がないと思います(つまり、関数をデフォルトの動作のままにすることを意味します)。

sort -fファイル

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

間違った(そして奇妙なことに)誤った文法であるStephen Rauchの修正と編集に感謝します。

0
1m.0g