Bash Globbing no como se esperaba

8

Esta es una pregunta de tarea:

Haga coincidir todos los nombres de archivo con 2 o más caracteres que comiencen con una letra minúscula, pero no terminen con una letra mayúscula.

No entiendo por qué mi solución no funciona.

Entonces ejecuté lo siguiente:

touch aa
touch ha
touch ah
touch hh
touch a123e
touch hX
touch Ax

ls [a-z]*[!A-Z]

Salida:

aa  ha

Mi pregunta: ¿Por qué no coincide con "ah", "hh" o "a123e"?

Corazón oscuro
fuente
Funciona para mí correctamente bajo mkshshell, pero no bash --posix, así que debe haber alguna regla específica para bash`
Sergiy Kolodyazhnyy
@Serg, tenga en cuenta que POSIX no especifica el comportamiento de [AZ], excepto en la configuración regional C. mkshal igual que zsh's [A-Z]no coincide con el É, por ejemplo. Los [A-Z]partidos de ksh93 están encendidos Épero no encendidos h.
Stéphane Chazelas

Respuestas:

9

Este es un problema local . En su configuración regional, se [A-Z]expande a algo como [AbBcZ...zZ](más probablemente otros como caracteres acentuados), por [^A-Z]lo tanto, en realidad significa "archivos que terminan con a" en su ejemplo (y solo en su ejemplo).

Si desea evitar tal sorpresa, una forma es establecerla, LC_COLLATE=C ya que la clasificación es la parte de la configuración regional que es responsable del orden de clasificación. Además, vacíe LC_ALLsi está configurado, ya que tendría prioridad.

$ ls [a-z]*[^A-Z]
aa  ha

$ ( LC_ALL=; LC_COLLATE=C; ls [a-z]*[^A-Z] )
a123e  aa  ah  ha  hh

O, mejor, probablemente sea preferible no cambiar la configuración regional y usar las clases apropiadas: en [:lower:]lugar de [a-z]y en [:upper:]lugar de [A-Z].

$ ls [[:lower:]]*[^[:upper:]]
a123e  aa  ah  ha  hh

O use la globasciirangesopción de bash :

$ shopt -s globasciiranges
$ ls [a-z]*[^A-Z]
a123e  aa  ah  ha  hh

$ shopt -u globasciiranges
$ ls [a-z]*[^A-Z]
aa  ha
xhienne
fuente
@heemayl, no LC_ALL=C ls [a-z]*[^A-Z]solo afectaría lsla configuración regional, no la configuración regional utilizada por el shell para expandir el globo o analizar esa línea de comando.
Stéphane Chazelas
No necesita exportar LC_xxxpara que se aplique al glob, pero sería preferible para que ls obtenga la misma configuración regional.
Stéphane Chazelas
1
Tenga en cuenta que en un entorno local donde el juego de caracteres es GB18030, por ejemplo, con el enfoque LC_ALL = C, no coincidiría en un archivo llamado, test-鏏por ejemplo, porque una vez que cambia el juego de caracteres al de la configuración regional C, se convierte en <0xe7>A. IOW, al cambiar LC_CTYPE, obtienes diferentes caracteres.
Stéphane Chazelas
1
Tenga en cuenta que sospecho que [AZ] en la configuración regional del OP cubre más que AbBcC ... zZ. Probablemente también tiene é, Á(pero probablemente no Ź). IOW, usar [A-Z]tiene poco sentido fuera de la configuración regional C.
Stéphane Chazelas
@ StéphaneChazelas Gracias por sus excelentes comentarios. Respuesta actualizada Creo que tomé todo en cuenta.
xhienne