Estoy usando bash en Linux. Estoy obteniendo un éxito de la siguiente declaración if, pero ¿no debería esto devolver un código de error?
if [[ ■ = [⅕⅖⅗] ]] ; then echo yes ; fi
El cuadrado NO es igual a ninguno de los caracteres, por lo que no veo por qué obtengo un código de éxito.
Es importante para mí mantener los corchetes dobles en mi caso.
¿Hay alguna otra manera de hacer un rango en este escenario, o qué otras sugerencias?
C
no lo haré aquí, ya que no son caracteres de un solo byte.C.UTF-8
haría donde esté disponible.Respuestas:
Esa es una consecuencia de que los personajes tienen el mismo orden de clasificación.
También notarás que
devuelve solo una línea.
O eso:
devuelve verdadero (como lo requiere POSIX).
La mayoría de las configuraciones regionales que se envían con sistemas GNU tienen varios caracteres (e incluso secuencias de caracteres (secuencias de clasificación)) que tienen el mismo orden de clasificación. En el caso de esos ■ ⅕⅖⅗, es porque el orden no está definido, y aquellos caracteres cuyo orden no está definido terminan teniendo el mismo orden de clasificación en los sistemas GNU. Hay caracteres que se definen explícitamente como que tienen el mismo orden de clasificación como Ș y Ş (aunque no hay una lógica real o coherencia aparente (para mí de todos modos) sobre cómo se hace).
Esa es la fuente de comportamientos bastante sorprendentes y falsos. Recientemente he planteado el tema en la lista de correo del grupo de Austin (el cuerpo detrás de POSIX y la Especificación Única de UNIX) y la discusión aún continúa a partir del 03/04/2015.
En este caso, no
[y]
debería estar claro si debería coincidir conx
dóndex
yy
ordenar lo mismo, pero dado que una expresión de paréntesis debe coincidir con un elemento de clasificación, eso sugiere quebash
se espera el comportamiento.En cualquier caso, supongo
[⅕-⅕]
o al menos[⅕-⅖]
debería coincidir■
.Notarás que las diferentes herramientas se comportan de manera diferente. ksh93 se comporta como
bash
GNUgrep
osed
no. Algunos otros depósitos tienen comportamientos diferentes, a algunos les gustayash
aún más con errores.Para tener un comportamiento consistente, necesita una configuración regional donde todos los caracteres se ordenan de manera diferente. La configuración regional C es la típica. Sin embargo, el conjunto de caracteres en la configuración regional C en la mayoría de los sistemas es ASCII. En los sistemas GNU, generalmente tiene acceso a un
C.UTF-8
entorno local que se puede utilizar para trabajar en el carácter UTF-8.Entonces:
o el equivalente estándar:
debería devolver falso.
Otra alternativa sería establecer solo
LC_COLLATE
en C, que funcionaría en los sistemas GNU, pero no necesariamente en otros en los que podría no especificarse el orden de clasificación del carácter de varios bytes.Una lección de eso es que la igualdad no es una noción tan clara como cabría esperar cuando se trata de comparar cadenas. Igualdad podría significar, de lo más estricto a lo menos estricto.
Ahora, para 2 o 3, se supone que ambas cadenas contienen caracteres válidos. En UTF-8 y algunas otras codificaciones, algunas secuencias de bytes no forman caracteres válidos.
1 y 2 no son necesariamente equivalentes por eso o porque algunos caracteres pueden tener más de una codificación posible. Ese suele ser el caso de codificaciones con estado como ISO-2022-JP, donde
A
se pueden expresar como41
o1b 28 42 41
(1b 28 42
siendo la secuencia para cambiar a ASCII y se pueden insertar tantas de las que desee, eso no hará la diferencia), aunque yo no esperaría que esos tipos de codificación aún estén en uso, y las herramientas GNU al menos generalmente no funcionan correctamente con ellas.También tenga en cuenta que la mayoría de las utilidades que no son GNU no pueden manejar el valor de 0 bytes (el carácter NUL en ASCII).
Cuál de esas definiciones se usa depende de la utilidad y la implementación o versión de la utilidad. POSIX no es 100% claro en eso. En la configuración regional C, los 3 son equivalentes. Fuera de ese YMMV.
fuente
é
yé
ser la misma cadena, pero noe
. La noción de orden de clasificación de POSIX rara vez es correcta, se basa demasiado en los caracteres y no tiene en cuenta las formas más comunes de ordenar cadenas (por ejemplo, los diccionarios franceses no usan un orden lexicográfico para ordenar palabras: hacen un primer paso lexicográfico con acentos ignorados y luego use acentos para decidir los lazos).Lo estás haciendo mal
=
y==
no eres lo mismo.Prueba estos ejemplos:
fuente
=
debe usarse para verificar la igualdad. El problema son las comillas faltantes, no el operador.man bash
dice en la[[
sección: "El operador = es equivalente a ==".[[...]]
operador. Y = y == son los mismos en los shells donde se implementa (ksh / bash / zsh) y para la coincidencia de patrones, no la igualdad.