GNU/Linux >> Tutoriales Linux >  >> Linux

¿Por qué [a-z] coincide con letras minúsculas en Bash?

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 y z (en [a-z] ) son TODAS letras mayúsculas, excepto Z .
  • Entre A y Z (en [A-Z] ) son TODAS letras minúsculas, excepto a .

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

Linux
  1. ~ Siempre es igual a $home?

  2. ¿Por qué Sudo ignora los alias?

  3. ¿Por qué no puedo usar Cd en un script Bash?

  4. ¿Por qué no funciona el autocompletado cuando se escribe un nombre de comando después de `fuente`?

  5. ¿Por qué el tiempo de Unix comienza en 1970-01-01?

¿Qué significa Env X=() { ::}; Command' Bash Do y por qué es inseguro?

¿Por qué el archivo de traducción de Bash no contiene todos los textos de error?

Bash:¿Por qué la secuencia de comandos principal no termina en SIGINT cuando la secuencia de comandos secundaria atrapa a SIGINT?

¿Qué hace 'bash -c'?

¿Por qué Ctrl + V no se pega en Bash (shell de Linux)?

¿Cómo prueba bash 'falso'?