En todos los shells que conozco, rm [A-Z]*
elimina todos los archivos que comienzan con una letra mayúscula, pero con bash elimina todos los archivos que comienzan con una letra.
Como este problema existe en Linux y Solaris con bash-3 y bash-4, no puede ser un error causado por un patrón de comparación de errores en libc o una definición de configuración regional incorrecta.
¿Este comportamiento extraño y arriesgado es intencionado o es solo un error que existe sin corregir desde hace muchos años?
Respuesta aceptada:
Tenga en cuenta que al usar expresiones de rango como [a-z], se pueden incluir letras del otro caso, según la configuración de LC_COLLATE.
LC_COLLATE
es una variable que determina el orden de clasificación utilizado al clasificar los resultados de la expansión del nombre de la ruta y determina el comportamiento de las expresiones de rango, las clases de equivalencia y las secuencias de clasificación dentro de la expansión del nombre de la ruta y la coincidencia de patrones.
Considere lo siguiente:
$ touch a A b B c C x X y Y z Z
$ ls
a A b B c C x X y Y z Z
$ echo [a-z] # Note the missing uppercase "Z"
a A b B c C x X y Y z
$ echo [A-Z] # Note the missing lowercase "a"
A b B c C x X y Y z Z
Observe cuando el comando echo [a-z]
se llama, la salida esperada sería todos los archivos con caracteres en minúsculas. Además, con echo [A-Z]
, se esperarían archivos con caracteres en mayúsculas.
Intercalaciones estándar con configuraciones regionales como en_US
tener el siguiente orden:
aAbBcC...xXyYzZ
- Entre
a
yz
(en[a-z]
) son TODAS letras mayúsculas, exceptoZ
. - Entre
A
yZ
(en[A-Z]
) son TODAS letras minúsculas, exceptoa
.
Ver:
aAbBcC[...]xXyYzZ
| |
from a to z
aAbBcC[...]xXyYzZ
| |
from A to Z
Si cambia el LC_COLLATE
variable a C
se ve como se esperaba:
$ export LC_COLLATE=C
$ echo [a-z]
a b c x y z
$ echo [A-Z]
A B C X Y Z
Entonces, no es un error , es un problema de intercalación .
En lugar de expresiones de rango, puede usar clases de caracteres definidas por POSIX, como upper
o lower
. Funcionan también con diferentes LC_COLLATE
configuraciones e incluso con caracteres acentuados :
$ echo [[:lower:]]
a b c x y z à è é
$ echo [[:upper:]]
A B C X Y Z