GNU/Linux >> Linux Esercitazione >  >> Linux

Specificare l'ordinamento con LC_COLLATE in modo che le minuscole siano prima delle maiuscole

Non conosco nessun locale che, per impostazione predefinita, ordina in questo ordine. La soluzione consiste nel creare una locale personalizzata con un ordinamento personalizzato. Se qualcuno, quattro anni dopo, vuole ordinare in modo personalizzato, ecco il trucco.

La stragrande maggioranza delle impostazioni locali non specifica il proprio ordinamento, ma piuttosto copia l'ordinamento definito in /usr/share/i18n/locales/iso14651_t1_common quindi questo è ciò che vorrai modificare. Piuttosto che cambiare l'ordinamento per quasi tutte le impostazioni locali modificando l'originale iso14651_t1_common , ti suggerisco di farne una copia. Dettagli su come funziona l'ordinamento e su come creare un locale personalizzato nel tuo $HOME directory senza accesso root si trovano in questa risposta a una domanda simile.

Dai un'occhiata a come a e A sono ordinati in base alle loro voci in iso14651_t1_common :

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

b e B sono simili:

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

Lo vediamo al primo passaggio, entrambi a e A hanno il simbolo di fascicolazione <a> , mentre entrambi b e B hanno il simbolo di fascicolazione <b> . Da <a> appare prima di <b> in iso14651_t1_common , a e A sono legati prima di b e B . Il secondo passaggio non risolve i pareggi perché tutti e quattro i caratteri hanno il simbolo di fascicolazione <BAS> , ma durante il terzo passaggio i pareggi vengono risolti perché il simbolo di fascicolazione per le lettere minuscole <MIN> appare alla riga 3467, prima del simbolo di fascicolazione per le lettere maiuscole <CAP> (riga 3488). Quindi l'ordinamento finisce con a , A , b , B .

Scambiando il primo e il terzo simbolo di fascicolazione, le lettere vengono ordinate prima per maiuscolo/minuscolo (inferiore poi superiore), quindi per accento (<BAS> significa non accentato), quindi in ordine alfabetico. Tuttavia , entrambi <MIN> e <CAP> vengono prima delle cifre numeriche, quindi questo avrebbe l'effetto indesiderato di mettere le cifre dopo le lettere.

Il modo più semplice per tenere prima le cifre mentre crei tutto le lettere minuscole precedono tutto lettere maiuscole è quello di forzare la parità di tutte le lettere durante il primo confronto impostandole tutte uguali a <a> . Per assicurarti che vengano ordinati alfabeticamente all'interno di maiuscole e minuscole, cambia l'ultimo simbolo di fascicolazione da IGNORE al primo simbolo di fascicolazione corrente. Seguendo questo schema, a diventerebbe:

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

A diventerebbe:

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

b diventerebbe:

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

B diventerebbe:

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

e così via per il resto delle lettere.

Dopo aver creato una versione personalizzata di iso14651_t1_common , segui le istruzioni nella risposta collegata sopra per compilare la tua lingua personalizzata.


Impostazione LC_COLLATE=C non è sempre sufficiente ordinare le maiuscole prima delle minuscole. Potrebbe essere necessario impostare LC_ALL=C .

Ciò terrà conto anche dei caratteri non alfanumerici e anche non stampabili, ma se non vuoi che ci siano opzioni -d e -i (descritto in man sort ) per disattivarlo.

Tuttavia, probabilmente fallirà gravemente con input multibyte, come UTF-8 con caratteri non ASCII.

Per ottenere lettere minuscole (in ordine) prima di maiuscole (in ordine), il modo migliore a cui riesco a pensare che non implichi l'apertura di un linguaggio di programmazione completo è invertire il caso di tutte le lettere prima dell'ordinamento e invertirle indietro successivamente.

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

Non sono un esperto ma non ho mai visto impostazioni locali che definiscano le regole di confronto in questo modo. AFAIK questa raccolta è solo in C dove si basa su valori ASCII. (Normalmente lo risolverei solo con uno script.)

Tuttavia, non l'ho mai fatto, ma potresti voler dare un'occhiata alle manpage localedef(1) e locale(5) per capire come vengono definite le impostazioni locali e alla fine definirne una tua.

Inoltre, non dimenticare che se sono presenti segni diacritici o caratteri speciali, C locale non li tratterà come vorresti. Ad esempio, non inserirà á vicino a a o Ł vicino a L . In tali casi, il locale nativo della lingua sarebbe probabilmente un punto di partenza migliore.


Linux
  1. Analizza il kernel Linux con ftrace

  2. Ordina il comando in Linux con esempi

  3. Disabilita l'accesso con l'account root

  4. Contando i caratteri di ogni riga con Wc?

  5. Ordinamento di più chiavi con Unix sort

Impara Linux con Raspberry Pi

Comando di ordinamento Linux con esempi

10 esempi utili del comando di ordinamento in Linux

Proteggi Linux con il file Sudoers

Ordinamento sull'ultimo campo di una riga

Aggiungi spazio prima della lettera maiuscola