[A-Z]
nelle bash
partite tutti gli elementi di confronto (i caratteri ma chiamano anche sequenza di caratteri come Dsz
nelle localizzazioni ungheresi) che ordinano dopo A
e ordinano prima Z
. Nel tuo locale, c
probabilmente ordina tra-B e C.
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | sort
a
A
á
b
B
c
C
Ç
z
Z
Ẑ
Quindi c
o z
sarebbe abbinato da [A-Z]
, ma non Ẑ
o a
.
$ printf '%s\n' A a á b B c C Ç z Z Ẑ |
pipe> bash -c 'while IFS= read -r x; do case $x in [A-Z]) echo "$x"; esac; done'
A
á
b
B
c
C
Ç
z
Z
Nella locale C, l'ordine sarebbe:
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | LC_COLLATE=C sort
A
B
C
Z
a
b
c
z
Ç
á
Ẑ
Così [A-Z]
sarebbe partita A
, B
, C
, Z
, ma non Ç
e ancora non Ẑ
.
Se si desidera abbinare lettere maiuscole (in qualsiasi script), è possibile utilizzare [[:upper:]]
invece. Non esiste un modo integrato bash
per abbinare solo lettere maiuscole nello script latino (tranne elencandole singolarmente).
Se si desidera far corrispondere la A
di Z
inglese lettere senza segni diacritici, è possibile utilizzare [A-Z]
o [[:upper:]]
, ma nel C
locale (supponendo che i dati non sono codificati in set di caratteri come BIG5 o GB18030 che ha diversi personaggi le cui codifica contiene la codifica di quelle lettere) o lista individualmente ( [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
).
Nota che c'è qualche variazione tra le shell.
For zsh
, bash -O globasciiranges
(opzione stranamente nominata introdotta in bash-4.3), schily-sh
e yash
, [A-Z]
corrisponde ai caratteri il cui punto di codice è compreso tra quello di A
e quello di Z
, quindi sarebbe equivalente al comportamento di bash
nella locale C.
Per ash, mksh e conchiglie antiche, come zsh
sopra ma limitate ai set di caratteri a byte singolo. Cioè, ad esempio in una locale UTF-8, [É-Ź]
non corrisponderebbe Ó
, ma dato che [<c3><89>-<c5><b9>]
, corrisponderebbe a valori di byte da 0x89 a 0xc5!
ksh93
si comporta come bash
se non fosse trattato come intervalli di casi speciali le cui estremità iniziano entrambe con lettere minuscole o lettere maiuscole. In tal caso, corrisponde solo agli elementi di fascicolazione che si ordinano tra quelle estremità, ma che sono (o il loro primo carattere per gli elementi di fascicolazione multi-carattere) anche in minuscolo (o maiuscolo rispettivamente). Quindi [A-Z]
ci sarebbe corrispondenza su É
, ma non su e
come e
fa l'ordinamento tra A
e Z
ma non è maiuscolo come A
e Z
.
Per i fnmatch()
pattern (come in find -name '[A-Z]'
) o le espressioni regolari di sistema (come in grep '[A-Z]'
), dipende dal sistema e dalle impostazioni locali. Ad esempio, su un sistema GNU qui, [A-Z]
non corrisponde x
nella en_GB.UTF-8
locale, ma lo fa in th_TH.UTF-8
quello. Non mi è chiaro quali informazioni utilizzi per determinarlo, ma apparentemente si basa su una tabella di ricerca derivata da dati locali LC_COLLATE ).
Tutti i comportamenti sono consentiti da POSIX poiché POSIX lascia il comportamento degli intervalli non specificato in locali diversi dalla locale C. Ora possiamo discutere dei vantaggi di ciascun approccio.
bash
L'approccio ha molto senso, come nel caso [C-G]
, vogliamo i personaggi tra C
e G
. E l'utilizzo dell'ordinamento dell'utente per ciò che determina ciò che sta nel mezzo è l'approccio più logico.
Ora, il problema è che rompe le aspettative di molte persone, in particolare quelle abituate al comportamento tradizionale del pre-Unicode, anche nei giorni pre-internazionalizzazione. Mentre da un utente normale, può sembrare che [C-I]
includa h
la h
lettera tra C
e I
e che [A-g]
non includa Z
, è una questione diversa per le persone che hanno a che fare con ASCII solo per decenni.
Tale bash
comportamento è anche diverso dalla [A-Z]
corrispondenza dell'intervallo in altri strumenti GNU come nelle espressioni regolari GNU (come in grep
/ sed
...) o fnmatch()
come in find -name
.
Significa anche che ciò che [A-Z]
corrisponde varia con l'ambiente, con il sistema operativo e con la versione del sistema operativo. Anche il fatto che [A-Z]
corrisponda ad Á ma non a Ź non è ottimale.
Per zsh
/ yash
, utilizziamo un diverso ordinamento. Invece di fare affidamento sulla nozione dell'utente di ordine dei caratteri, utilizziamo i valori del codice punto carattere. Ciò ha il vantaggio di essere facile da capire, ma dal punto di vista pratico di pochi, al di fuori di ASCII, non è molto utile. [A-Z]
corrisponde alle 26 lettere maiuscole inglese-americano, [0-9]
corrisponde alle cifre decimali. Ci sono punti di codice in Unicode che seguono l'ordine di alcuni alfabeti, ma questo non è generalizzato e non può essere generalizzato poiché comunque persone diverse che usano uno stesso script non concordano necessariamente sull'ordine delle lettere.
Per shell tradizionali e mksh, dash, è rotto (ora che la maggior parte delle persone usa caratteri multi-byte), ma principalmente perché non hanno ancora il supporto multi-byte. L'aggiunta del supporto multi-byte a shell come bash
ed zsh
è stata un grande sforzo ed è ancora in corso. yash
(una shell giapponese) è stata inizialmente progettata con supporto multi-byte sin dall'inizio.
L'approccio di ksh93 ha il vantaggio di essere coerente con le espressioni regolari o fnmatch del sistema () (o almeno sembra almeno sui sistemi GNU). Lì, non infrange le aspettative di alcune persone in quanto [A-Z]
non include lettere minuscole, [A-Z]
include É
(e Á, ma non Ź). Non è coerente con sort
o in generale strcoll()
ordine.
locale
? Non riesco a riprodurlo (touch foo; echo [A-Z]*
genera il modello letterale, non "pippo", in una directory altrimenti vuota).