Esta é uma pergunta de lição de casa:
Combine todos os nomes de arquivos com 2 ou mais caracteres que começam com uma letra minúscula, mas não terminam com uma letra maiúscula.
Não entendo por que minha solução não está funcionando.
Então eu executei o abaixo:
touch aa
touch ha
touch ah
touch hh
touch a123e
touch hX
touch Ax
ls [a-z]*[!A-Z]
Resultado:
aa ha
Minha pergunta: por que não corresponde a "ah", "hh" ou "a123e"?
mksh
shell, mas nãobash --posix
, então deve haver alguma regra específica para o bash` #mksh
comozsh
's[A-Z]
não corresponde emÉ
por exemplo. As[A-Z]
partidas de ksh93 estão ativadas,É
mas não ativadash
.Respostas:
Este é um problema de localidade . No seu código de idioma,
[A-Z]
expande para algo como[AbBcZ...zZ]
(e provavelmente outros como caracteres acentuados), portanto,[^A-Z]
na verdade significa "arquivos que terminam coma
" no seu exemplo (e somente no seu exemplo).Se você deseja evitar essa surpresa, uma maneira é definir,
LC_COLLATE=C
pois o agrupamento faz parte das configurações de localidade responsáveis pela ordem de classificação. Além disso, esvazieLC_ALL
se estiver definido, pois isso teria precedência.Ou, melhor, provavelmente é preferível não alterar as configurações de localidade e usar as classes apropriadas: em
[:lower:]
vez de[a-z]
e em[:upper:]
vez de[A-Z]
.Ou use a
globasciiranges
opção do bash :fonte
LC_ALL=C ls [a-z]*[^A-Z]
afetaria apenas als
localidade de, não a localidade usada pelo shell para expandir a glob ou analisar essa linha de comando.LC_xxx
para que se aplique à glob, mas seria preferível que o ls obtenha o mesmo código de idioma.test-鏏
por exemplo, porque depois que você altera o conjunto de caracteres para o código de idioma C,鏏
fica<0xe7>A
. IOW, ao alterar LC_CTYPE, você obtém caracteres diferentes.é
,Á
(mas provavelmente nãoŹ
). IOW, usar[A-Z]
faz pouco sentido fora do código C.