[A-Z]in bashcorresponde a todos os elementos de intercalação (caracteres, mas também podem ser sequências de caracteres, como Dsznas localidades húngaras) que são classificadas após Ae classificadas antes Z. No seu local, cprovavelmente classifica entre B e C.
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | sort
a
A
á
b
B
c
C
Ç
z
Z
Ẑ
Então, cou zseria correspondido por [A-Z], mas não Ẑou 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
No código C, o pedido seria:
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | LC_COLLATE=C sort
A
B
C
Z
a
b
c
z
Ç
á
Ẑ
Então [A-Z]iria corresponder A, B, C, Z, mas não Çe ainda não Ẑ.
Se você deseja combinar com letras maiúsculas (em qualquer script), você pode usá-lo [[:upper:]]. Não existe uma maneira incorporada bashde combinar apenas letras maiúsculas no script latino (exceto listando-as individualmente).
Se você quiser combinar com o Ade Z Inglês letras sem diacríticos, você pode usar [A-Z]ou [[:upper:]]mas no Clocal (assumindo que os dados não são codificados em conjuntos de caracteres como BIG5 ou GB18030, que tem vários personagens cujas codificação contém a codificação dessas cartas) ou lista eles individualmente ( [ABCDEFGHIJKLMNOPQRSTUVWXYZ]).
Observe que há alguma variação entre as conchas.
For zsh, bash -O globasciiranges(opção de nome estranho introduzida no bash-4.3), schily-she yash, [A-Z]corresponde aos caracteres cujo ponto de código está entre o de Ae o de Z, portanto seria equivalente ao comportamento do código de bashidioma C.
Para cinzas, mksh e cascas antigas, o mesmo que zshacima, mas limitado a conjuntos de caracteres de byte único. Ou seja, em um código de idioma UTF-8, por exemplo, [É-Ź]não corresponderia Ó, mas, como isso [<c3><89>-<c5><b9>], corresponderia aos valores de bytes 0x89 a 0xc5!
ksh93comporta-se como bashexceto que trata como intervalos de casos especiais cujas extremidades começam com letras minúsculas ou maiúsculas. Nesse caso, ele corresponde apenas aos elementos de intercalação que se classificam entre essas extremidades, mas que são (ou o primeiro caractere para elementos de intercalação de vários caracteres) também em minúsculas (ou maiúsculas, respectivamente). Portanto [A-Z], haveria correspondência em É, mas não em, ecomo ea classificação entre Ae Zmas não é maiúscula como Ae Z.
Para fnmatch()padrões (como em find -name '[A-Z]') ou expressões regulares do sistema (como em grep '[A-Z]'), isso depende do sistema e da localidade. Por exemplo, em um sistema GNU aqui, [A-Z]não corresponde no código xdo en_GB.UTF-8idioma, mas no th_TH.UTF-8. Não está claro para mim quais informações são usadas para determinar isso, mas aparentemente são baseadas em uma tabela de pesquisa derivada dos dados do código de idioma LC_COLLATE ).
Todos os comportamentos são permitidos pelo POSIX, pois o POSIX deixa o comportamento dos intervalos não especificados em códigos de idioma que não sejam o código C. Agora podemos discutir sobre os benefícios de cada abordagem.
bashA abordagem de faz muito sentido [C-G], pois queremos que os personagens entre Ce G. E usar a ordem de classificação do usuário para o que determina o que é intermediário é a abordagem mais lógica.
Agora, o problema é que isso quebra as expectativas de muitas pessoas, especialmente aquelas que estão acostumadas com o comportamento tradicional do pré-Unicode, mesmo nos dias anteriores à internacionalização. Embora, para um usuário normal, faça sentido que [C-I]inclua hcomo a hletra está entre Ce Ie que [A-g]não inclua Z, é uma questão diferente para as pessoas que lidam com o ASCII apenas por décadas.
Esse bashcomportamento também é diferente do [A-Z]intervalo correspondente em outras ferramentas GNU, como nas expressões regulares do GNU (como em grep/ sed...) ou fnmatch()como em find -name.
Isso também significa que o que [A-Z]corresponde varia de acordo com o ambiente, com o sistema operacional e com a versão do sistema operacional. O fato de [A-Z]corresponder Á, mas não Ź também é subótimo.
Para zsh/ yash, usamos uma ordem de classificação diferente. Em vez de confiar na noção de ordem de caracteres do usuário, usamos os valores do código do ponto de caractere. Isso tem o benefício de ser fácil de entender, mas de um ponto prático de poucos, fora do ASCII, não é muito útil. [A-Z]corresponde às 26 letras maiúsculas em inglês dos EUA, [0-9]corresponde aos dígitos decimais. Existem pontos de código no Unicode que seguem a ordem de alguns alfabetos, mas isso não é generalizado e não pode ser generalizado, pois pessoas diferentes que usam o mesmo script não necessariamente concordam com a ordem das letras.
Para shells e mksh tradicionais, traço, está quebrado (agora que a maioria das pessoas usa caracteres de vários bytes), mas principalmente porque ainda não têm suporte para vários bytes. A adição de suporte de vários bytes a shells como bashe zshtem sido um grande esforço e ainda está em andamento. yash(shell japonês) foi projetado inicialmente com suporte a vários bytes desde o início.
A abordagem do ksh93 tem o benefício de ser consistente com as expressões regulares do sistema ou fnmatch () (ou pelo menos parece ser pelo menos nos sistemas GNU). Lá, isso não quebra a expectativa de algumas pessoas, pois [A-Z]não inclui letras minúsculas, [A-Z]inclui É(e Á, mas não Ź). Não é consistente com sortou geralmente strcoll()ordem.
locale? Não consigo reproduzir isso (touch foo; echo [A-Z]*gera o padrão literal, não "foo", em um diretório vazio).