Come faccio a rendere prima i caratteri di sottolineatura?


20

Mi piace essere in grado di nominare file e directory con un prefisso di sottolineatura se è qualcosa che voglio mantenere separato da altri file e directory allo stesso livello. Su Windows e Mac, ad esempio, il prefisso di un file con un trattino basso lo ordina in cima, davanti ai file che iniziano con un carattere alfanumerico.

Ho scoperto che ha a che fare con LC_COLLATE e la mia locale corrente (en_US). Va bene, anche se davvero non capisco perché en_US non si ordina come previsto.

Sulla base delle impostazioni internazionali del sito dimostrativo ICU Collate su en_US_POSIX sembra certamente avere l'ordinamento che sto cercando (devi modificare i dati di esempio e aggiungere alcuni caratteri di sottolineatura per provarlo). Ma non vedo davvero come applicarlo nella mia shell Linux.

Idealmente, mi piacerebbe essere in grado di impostare qualcosa nella mia configurazione di bash in modo che prima di tutto selezioni i caratteri di sottolineatura. Come potrei fare per fare questo?


Non riesco a riprodurre usando ICU Collate con valori predefiniti o con en_US_POSIX.txt tramite "Scarica regole per impostazioni internazionali". Puoi spiegare le impostazioni che hai usato?
Mikel,


@Mikel usando il link che ho fornito sopra, aggiungi alcuni trattini bassi ai dati del test e poi invia per vedere i risultati dell'ordinamento.
Tom Auger,

È esattamente quello che ho fatto, e le stringhe che iniziano con i trattini bassi vengono ordinate nel mezzo anziché all'inizio, come se i trattini bassi non fossero presenti.
Mikel,

1
Una domanda correlata, che riguarda la modifica effettiva della definizione dell'ordine di confronto, è unix.stackexchange.com/questions/421908 .
JdeBP,

Risposte:


5

Se non riesci lsa ordinare nel modo desiderato, prova l'espansione della shell.

È possibile utilizzare i modelli di nomi file da eseguire lscon un elenco di file che la shell ha già ordinato, ignorando il metodo che lsutilizza.

ls -lf _* [!_]*

Supponendo di avere i file

_a a _b b _c c

è come correre

ls -lf _a _b _c a b c

Spiegazione:

_* è un modello di shell che corrisponde a qualsiasi nome di file che inizia con un carattere di sottolineatura, espanso in ordine alfabetico.

[!_]*corrisponde a qualsiasi nome di file che non inizia con un carattere di sottolineatura, espanso in ordine alfabetico.

-fdice lsdi non ordinare, perché la shell lo ha già fatto.

Ulteriori informazioni: espansione del nome file bash

Se ci sono directory nella directory corrente, vorrai eseguire il comando in questo modo per evitare di elencare i file nelle directory:

ls -lfd _* [!_]*

7
A proposito, DOS / Windows / OSX non mettono davvero i caratteri di sottolineatura prima di ogni altra cosa: si dividono in maiuscolo / minuscolo con il carattere di sottolineatura messo prima delle lettere, ma alcuni altri caratteri di punteggiatura vanno prima o dopo il carattere di sottolineatura. L'uso _per far apparire prima i file è un hack specifico del sistema operativo; e la versione unix di questo hack è di iniziare il nome del file con una lettera maiuscola: la convenzione unix predefinita prevede l'uso solo di lettere minuscole nei nomi dei file.
Gilles 'SO- smetti di essere malvagio' il

4
O zeri; es 00README.
Mattdm,

1
@Gilles +1 per la migliore pratica unix di usare i tappi su file importanti per renderli i primi. Alla fine della giornata, se questa è la convenzione, è probabilmente meglio che io semplicemente adotti questo, piuttosto che tentare di forzare unix a comportarsi come fanno gli altri sistemi operativi in ​​modo da poter usare convenzioni sviluppate per Mac o Windows. Grazie per l'ottimo consiglio.
Tom Auger,

1
@TomAuger -fdice di lsnon fare il proprio ordinamento, quindi mostra i suoi argomenti nell'ordine in cui sono passati. Il risultato di ciascuna espansione jolly della shell _*ed [!_]*è un elenco lessicograficamente ordinato.
Gilles 'SO- smetti di essere malvagio' il

1
@TomAuger Gli argomenti da lsordinare (in due gruppi: quelli che iniziano con _, quindi gli altri) quando vengono generati dalla shell. Corri echo ls -lf _* [!_]*per vedere cosa succede. La -fbandiera dice di lsnon fare alcun ordinamento.
Gilles 'SO- smetti di essere malvagio' il

16

Se non ti interessa mescolare lettere minuscole e maiuscole, imposta la tua locale su C, che accetta i caratteri nel loro ordine numerico. _rientra tra maiuscole e minuscole.

$ LC_COLLATE=C ls    
BAR  FOO  _score  _under  hello  world
$ LC_COLLATE=en_US ls                    
BAR  FOO  hello  _score  _under  world

Le impostazioni locali LC_MESSAGES(lingua dei messaggi di errore), LC_CTYPE(set di caratteri) e LC_TIME(formato data e ora) sono molto utili. LC_COLLATEe di LC_NUMERICsolito sono più problemi di quanto valgono, non consiglio di impostarli. Il corretto ordinamento lessicografico è più complicato di quanto LC_COLLATEsi supponga che specifichi e può causare tutti i tipi di comportamenti strani quando si utilizzano intervalli di caratteri in espressioni regolari. LC_NUMERICè per lo più cosmetico, tranne quando qualcosa va terribilmente storto perché alcuni programmi hanno prodotto un numero con un separatore decimale diverso da ..


+1 Molto interessante. Quindi, usando questo modulo, stai impostando temporaneamente la variabile d'ambiente LC_COLLATE solo per quell'istanza di ls? È giusto?
Tom Auger,

1
Qualche modo per far apparire i caratteri di sottolineatura PRIMA delle lettere maiuscole?
Tom Auger,

1
@TomAuger Sì, VAR=value cmdinsiemi VARa valuesolo nell'ambiente di cmde non tocca il valore (o l'assenza di valore) nel guscio in cui lo si esegue. Per far apparire il carattere di sottolineatura prima di maiuscole, è necessario definire le proprie impostazioni locali. Questo è possibile, ma scomodo da usare, perché almeno sotto Linux, la libreria standard cerca solo le definizioni delle impostazioni locali /usr/lib/locale: non esiste alcuna ~/.localevariabile di ambiente in cui è possibile inserire le en_tomimpostazioni.
Gilles 'SO- smetti di essere malvagio' il

@TomAuger Se si tratta solo del lscomando, segui il suggerimento di Mikel .
Gilles 'SO- smetti di essere malvagio' il

2

Sfortunatamente Linux usa glibc per le sue informazioni sulla locale, non per ICU, quindi non c'è modo di applicarlo direttamente a Linux senza spendere molto adattare l'ICU in glibc o integrare le informazioni sulla locale in glibc.


-4

L'aggiunta -fdell'interruttore (nessun ordinamento) mi ha fatto mostrare in quel modo per me.

man ls

[root@dusknoir ~/java/test]# ls -fl
total 0
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 _1
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 _2
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 _3
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 1
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 2
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 3

6
Solo perché è così che vengono memorizzati nel filesystem.
Ignacio Vazquez-Abrams,

3
Ci dispiace, ma questa risposta è chiaramente sbagliata. Test: touch 3 1 _1 _3 2 _2 && ls -fluscite2 . 1 3 _2 _3 .. _1
Marco
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.