Verificar la longitud de una variable

27

Tengo que verificar la longitud de la lectura variable (mi script limita a cinco los caracteres insertados), pienso en algo como esto:

#!/bin/bash
read string
check=${#string}
echo $check
if [ $check -ge 5 ]; then echo "error" ; exit
else echo "done"
fi

¿Hay una solución más "elegante"?

Pol Hallen
fuente
1
Su script funciona correctamente en POSIX estándar /bin/sh. Debería considerar cambiar la línea shebang a #!/bin/shpara que sea más portátil y se ejecute en entornos donde bash no esté disponible. Además, /bin/shpodría ser un shell más liviano como el tablero que no está cargado con características destinadas para uso interactivo.
Celada
@Celada, cierto, sin embargo, en este caso, dash's ${#string}le daría la longitud en número de bytes en lugar de caracteres.
Stéphane Chazelas

Respuestas:

43

¿Mas elegante? No

¿Corto? Sí :)

#!/bin/bash
read string
if [ ${#string} -ge 5 ]; then echo "error" ; exit
else echo "done"
fi

Y si no tiene problemas para negociar más elegancia a favor de ser más corto, puede tener un script con 2 líneas menos:

#!/bin/bash
read string
[ ${#string} -ge 5 ] && echo "error" || echo "done"

Podrías usar corchetes dobles si crees que es más seguro. Explicación aquí .


fuente
3

Una alternativa compatible con Bourne ( ${#string}es POSIX pero no Bourne (no es probable que encuentre un shell Bourne en estos días)):

case $string in
  ?????*) echo >&2 Too long; exit 1;;
       *) echo OK
esac

Tenga en cuenta que para ambos ${#string}y ????, si será el número de bytes o caracteres dependerá del shell. Generalmente (y es requerido por POSIX), es el número de caracteres. Pero para algunos shells como dashese no son compatibles con varios bytes, en su lugar serán bytes.

Con mksh, necesita set -o utf8-mode(en configuraciones regionales UTF-8) para que comprenda los caracteres de varios bytes:

$ string=€€€ bash -c 'echo "${#string}"'
3
$ string=€€€ dash -c 'echo "${#string}"'
9
$ string=€€€ mksh -c 'echo "${#string}"'
9
$ string=€€€ mksh -o utf8-mode -c 'echo "${#string}"'
3
$ locale charmap
UTF-8
Stéphane Chazelas
fuente
fuera del tema, pero es echo Too longdiferente bajo el capó deecho 'Too long'
Steven Penny
Y, si va a imprimir cuando es "demasiado largo", puedo compactar aún más en mi ifopción :)
2
@StevenPenny, echo Too longpasa dos argumentos ( Tooy long) a los echoque las echosalidas están separadas por un espacio (y seguidas por una nueva línea), mientras que en echo 'Too long', pasamos un Too longargumento al echoque se muestra seguido por una nueva línea. Entonces es funcionalmente equivalente.
Stéphane Chazelas