GNU/Linux >> Belajar Linux >  >> Linux

Tentukan tata urutan dengan LC_COLLATE jadi huruf kecil sebelum huruf besar

Saya tidak tahu ada lokal yang, secara default, mengurutkan dalam urutan itu. Solusinya adalah membuat lokal khusus dengan tata urutan yang disesuaikan. Jika seseorang, empat tahun kemudian, ingin menyortir dengan cara khusus, inilah triknya.

Sebagian besar lokal tidak menentukan urutan pengurutan mereka sendiri, melainkan menyalin urutan pengurutan yang ditentukan di /usr/share/i18n/locales/iso14651_t1_common jadi itulah yang ingin Anda edit. Daripada mengubah tata urutan untuk hampir setiap lokal dengan memodifikasi iso14651_t1_common yang asli , saya sarankan Anda membuat salinan. Detail tentang cara kerja pengurutan dan cara membuat lokal khusus di $HOME Anda direktori tanpa akses root ditemukan di jawaban ini untuk pertanyaan serupa.

Lihatlah bagaimana a dan A diurutkan berdasarkan entri mereka di iso14651_t1_common :

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

b dan B mirip:

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

Kita melihat bahwa pada lintasan pertama, keduanya a dan A memiliki simbol penyusun <a> , sementara keduanya b dan B memiliki simbol penyusun <b> . Sejak <a> muncul sebelum <b> di iso14651_t1_common , a dan A terikat sebelum b dan B . Pass kedua tidak memutuskan ikatan karena keempat karakter memiliki simbol penyusun <BAS> , tetapi selama pass ketiga, ikatan diselesaikan karena simbol susunan untuk huruf kecil <MIN> muncul pada baris 3467, sebelum simbol susun untuk huruf kapital <CAP> (baris 3488). Jadi tata urutan berakhir sebagai a , A , b , B .

Menukar simbol susunan pertama dan ketiga akan mengurutkan huruf terlebih dahulu berdasarkan huruf besar-kecil (lebih rendah lalu atas), lalu berdasarkan aksen (<BAS> berarti tanpa aksen), kemudian dengan urutan abjad. Namun , keduanya <MIN> dan <CAP> datang sebelum angka numerik, jadi ini akan memiliki efek yang tidak diinginkan dari menempatkan angka setelah huruf.

Cara termudah untuk menyimpan angka terlebih dahulu sambil membuat semua huruf kecil datang sebelum semua huruf besar memaksa semua huruf untuk diikat selama perbandingan pertama dengan menyetel semuanya sama dengan <a> . Untuk memastikan bahwa mereka mengurutkan menurut abjad dalam huruf besar-kecil, ubah simbol susunan terakhir dari IGNORE ke simbol penyusunan pertama saat ini. Mengikuti pola ini, a akan menjadi:

<U0061> <a>;<BAS>;<MIN>;<a> # 198 a

A akan menjadi:

<U0041> <a>;<BAS>;<CAP>;<a> # 517 A

b akan menjadi:

<U0062> <a>;<BAS>;<MIN>;<b> # 233 b

B akan menjadi:

<U0042> <a>;<BAS>;<CAP>;<b> # 550 B

dan seterusnya untuk surat-surat lainnya.

Setelah Anda membuat versi iso14651_t1_common yang disesuaikan , ikuti petunjuk dalam jawaban yang ditautkan di atas untuk mengompilasi lokal khusus Anda.


Menyetel LC_COLLATE=C tidak selalu cukup untuk mengurutkan huruf besar sebelum huruf kecil. Anda mungkin perlu menyetel LC_ALL=C .

Itu juga akan mempertimbangkan karakter non-alfanumerik dan bahkan tidak dapat dicetak, tetapi jika Anda tidak menginginkannya ada opsi -d dan -i (dijelaskan dalam man sort ) untuk akan mematikannya.

Ini mungkin akan gagal parah dengan input multibyte, seperti UTF-8 dengan karakter non-ASCII.

Untuk mendapatkan huruf kecil (dalam urutan) sebelum huruf besar (dalam urutan), cara terbaik yang dapat saya pikirkan yang tidak melibatkan pemecahan bahasa pemrograman yang lengkap adalah membalikkan kasus semua huruf sebelum mengurutkan, dan membalikkannya kembali setelah itu.

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

Saya bukan ahli tetapi saya belum pernah melihat lokal yang mendefinisikan susunan seperti ini. AFAIK susunan ini hanya di C yang didasarkan pada nilai ASCII. (Biasanya saya hanya akan menyelesaikan ini dengan skrip.)

Namun, saya belum pernah melakukan ini tetapi Anda mungkin ingin melihat halaman manual localedef(1) dan locale(5) untuk mendapatkan pemahaman tentang bagaimana lokal didefinisikan dan akhirnya menentukan lokal Anda sendiri.

Juga jangan lupa bahwa jika ada diakritik atau karakter khusus, lokal C tidak akan memperlakukannya seperti yang Anda inginkan. Misalnya, itu tidak akan menempatkan á dekat a atau Ł dekat L . Dalam kasus seperti itu, lokal asli bahasa tersebut mungkin akan menjadi titik awal yang lebih baik.


Linux
  1. Menyortir banyak kunci dengan pengurutan Unix

  2. '&&' vs. '&' dengan perintah 'test' di Bash

  3. Apakah mungkin memodifikasi elemen di DOM dengan Puppeteer sebelum membuat tangkapan layar?

  1. Analisis kernel Linux dengan ftrace

  2. Apa urutan default dari jenis Linux?

  3. Tambahkan spasi sebelum huruf besar

  1. Diurutkan dengan sort di baris perintah

  2. Urutkan Perintah di Linux dengan Contoh

  3. Menghitung Karakter Setiap Baris Dengan Wc?