2012-05-22 16 views
5

Dato il seguente:Perché la dichiarazione case non fa distinzione tra maiuscole e minuscole quando nocasematch è disattivato?

$ echo $BASH_VERSION 
4.2.10(1)-release 

$ shopt | fgrep case 
nocaseglob  off 
nocasematch  off 

$ case A in [a-z]) echo TRUE;; esac 
TRUE 

Mi aspetto che la lettera maiuscola Un dovrebbe non corrispondere alla classe di caratteri minuscoli di [a-z], ma lo fa. Perché questa partita non fallisce?

+0

'nocaseglob' è correlato:' Se impostata, bash corrisponde nomi di file in modo case-insensitive quando si esegue l'espansione del percorso (vedi espansione di percorso sopra) ', anche se il comportamento è ancora dispari. – Daenyth

risposta

7

Non è possibile utilizzare in modo affidabile il trattino in questo modo. Se io non uso trattini, esso funziona come previsto:

$ bash --version 
GNU bash, version 4.2.10(1)-release (x86_64-pc-linux-gnu) 
Copyright (C) 2011 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 

This is free software; you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. 
$ shopt -s nocasematch 
$ case A in [abc]) echo TRUE;; esac 
TRUE 
$ shopt -u nocasematch 
$ case A in [abc]) echo TRUE;; esac 
$ 

Ma con trattini, stampa VERO indipendentemente dall'impostazione di nocasematch.

Bash sta eseguendo la corrispondenza del modello qui. Controlla this section of the reference manual dove dice che usando il trattino MIGHT interpreta [a-z] come [A-Za-z]! Ti dice come ottenere l'interpretazione tradizionale (imposta LC_COLLATE o LC_ALL in C). Fondamentalmente, le impostazioni locali predefinite sono ordinate nell'ordine dei dizionari. Il manuale di riferimento spiega le cose abbastanza bene.

ADDENDUM

Va bene ho una trascrizione per voi.

$ shopt -u nocasematch 
$ case A in [a-z]) echo TRUE;; esac 
TRUE 
$ shopt -s nocasematch 
$ case A in [a-z]) echo TRUE;; esac 
TRUE 
$ LC_ALL=C 
$ shopt -u nocasematch 
$ case A in [a-z]) echo TRUE;; esac 
$ shopt -s nocasematch 
$ case A in [a-z]) echo TRUE;; esac 
TRUE 
7

Ha a che fare con le impostazioni locali. Nello specifico, la sequenza di confronto è quella con insensibilità al caso.

Per esempio, con LC_COLLATE set per en_AU.utf8 (il default sul mio sistema), si può vedere che include caratteri minuscoli e maiuscoli insieme:

pax> case A in [a-b]) echo TRUE;; esac 
TRUE 
pax> _ 

ma, se si sbarazzarsi della gamma specificatore, si funziona come previsto:

pax> case A in [ab]) echo TRUE;; esac 
pax> _ 

Questo perché il primo mezzo between a and b inclusive che, per quella sequenza di collazione, include A. Per quest'ultimo significa solo a e , non un intervallo che sarebbe interessato dalla sequenza di confronto.

Se si imposta la sequenza di confronto ad uno tra maiuscole e minuscole, funziona come ci si aspetta:

pax> export LC_COLLATE="C" 
pax> case A in [a-b]) echo TRUE;; esac 
pax> 

Se si desidera solo per fare questo come operazione una tantum senza modificare qualsiasi altra cosa, si può farlo in un sub-shell:

(export LC_COLLATE="C" ; case A in [a-b]) echo TRUE;; esac) 
Problemi correlati