Bash Globbing non come previsto


8

Questa è una domanda a casa:

Abbina tutti i nomi di file con 2 o più caratteri che iniziano con una lettera minuscola, ma non terminano con una lettera maiuscola.

Non capisco perché la mia soluzione non funzioni.

Quindi ho eseguito il seguito:

touch aa
touch ha
touch ah
touch hh
touch a123e
touch hX
touch Ax

ls [a-z]*[!A-Z]

Produzione:

aa  ha

La mia domanda: perché non corrisponde a "ah", "hh" o "a123e"?


Funziona per me correttamente sotto mkshshell, ma no bash --posix, quindi ci deve essere una regola specifica per bash`
Sergiy Kolodyazhnyy

@Serg, si noti che il comportamento di [AZ] non è specificato da POSIX tranne che nelle impostazioni locali C. mkshlike zsh's [A-Z]non corrisponde Éper esempio. Le [A-Z]partite di ksh93 sono accese Éma non accese h.
Stéphane Chazelas,

Risposte:


9

Questo è un problema di localizzazione . Nella tua lingua, si [A-Z]espande in qualcosa di simile [AbBcZ...zZ](più probabilmente altri come caratteri accentati), quindi in [^A-Z]realtà significa "file che terminano con a" nel tuo esempio (e solo nel tuo esempio).

Se si desidera evitare tale sorpresa, un modo è quello di impostare LC_COLLATE=C poiché la fascicolazione è la parte delle impostazioni internazionali che è responsabile dell'ordinamento. Inoltre, vuoto LC_ALLse è impostato, poiché avrebbe la precedenza.

$ ls [a-z]*[^A-Z]
aa  ha

$ ( LC_ALL=; LC_COLLATE=C; ls [a-z]*[^A-Z] )
a123e  aa  ah  ha  hh

O, meglio, è probabilmente preferibile non modificare le impostazioni locali e utilizzare le classi appropriate: [:lower:]anziché [a-z]e [:upper:]invece di [A-Z].

$ ls [[:lower:]]*[^[:upper:]]
a123e  aa  ah  ha  hh

Oppure usa l' globasciirangesopzione di bash :

$ shopt -s globasciiranges
$ ls [a-z]*[^A-Z]
a123e  aa  ah  ha  hh

$ shopt -u globasciiranges
$ ls [a-z]*[^A-Z]
aa  ha

@heemayl, no LC_ALL=C ls [a-z]*[^A-Z]influirebbe solo sulla lslocale, non sulla locale usata dalla shell per espandere il glob o analizzare quella riga di comando.
Stéphane Chazelas,

Non è necessario esportare LC_xxxperché si applichi al glob, ma sarebbe preferibile quindi otteniamo le stesse impostazioni locali.
Stéphane Chazelas,

1
Si noti che in una locale in cui il set di caratteri è GB18030, ad esempio, con l'approccio LC_ALL = C, non corrisponderebbe a un file chiamato test-鏏ad esempio perché una volta modificato il set di caratteri in quello della locale C, diventa <0xe7>A. IOW, quando cambi LC_CTYPE, ricevi diversi personaggi.
Stéphane Chazelas,

1
Si noti che sospetto che [AZ] nelle impostazioni locali dell'OP copra più di AbBcC ... zZ. Probabilmente ha anche é, Á(ma probabilmente non Ź). IOW, l'utilizzo [A-Z]ha poco senso al di fuori del locale C.
Stéphane Chazelas,

@ StéphaneChazelas Grazie per il tuo eccellente feedback. Risposta aggiornata Credo di aver preso tutto in considerazione.
Xhienne,
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.