script - ¿Cómo probar cadenas para lexicográfico menor o igual en Bash?
operadores logicos bash (5)
En Bash, ¿hay una forma sencilla de probar si una cadena es lexicográficamente menor o igual a otra?
Sé que puedes hacer:
if [[ "a" < "b" ]]
para probar la desigualdad estricta, o
if [[ 1 -le 1 ]]
para los numeros Pero -le
no parece funcionar con cadenas, y usar <=
da un error de sintaxis.
Necesitas usar ||
con una condición adicional en lugar de <=
:
[[ "$a" < "$b" || "$a" == "$b" ]]
Puedes voltear la comparación y firmar y probar negativamente:
$ a="abc"
$ b="abc"
$ if ! [[ "$b" > "$a" ]] ; then echo "a <= b" ; fi
a <= b
Si desea clasificar la secuencia de "A", entonces "a" y luego "B" ... use:
shopt -s nocaseglob
Si puede usar la sintaxis de Bash, vea las respuestas de @anubhava y @ gordon-davisson. Con la sintaxis de POSIX tiene dos opciones (tenga en cuenta las barras invertidas necesarias):
utilizando el operador -o
(OR):
[ "$a" /< "$b" -o "$a" = "$b" ] && echo "''$a'' LTE ''$b''" || echo "''$a'' GT ''$b''"
o usando la negación:
[ ! "$a" /> "$b" ] && echo "''$a'' LTE ''$b''" || echo "''$a'' GT ''$b''"
Prefiero la primera variante, porque ahora es más legible.
Solo niega la prueba mayor que:
if [[ ! "a" > "b" ]]
expr
método POSIX
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/expr.html
[ "$(expr abc /< acb)" = 1 ] || echo fail
[ "$(expr abc /< aac)" = 0 ] || echo fail
POSIX dice que expr
determina si el argumento es un entero o una cadena general, y si la comparación de cadenas:
devuelve el resultado de una comparación de cadena utilizando la secuencia de intercalación específica de la ubicación
sort
solución POSIX
Solo por diversión, usa expr
lugar.
No es infinitamente robusto para cadenas con nuevas líneas, pero ¿cuándo es cuando se trata de scripts de shell?
string_lte() (
s="$(printf "${1}/n${2}")"
if [ "$(printf "$s" | sort)" = "$s" ]; then
exit 0
else
exit 1
fi
)
string_lte abc adc || echo fail
string_lte adc adc || echo fail
string_lte afc adc && echo fail