112 votos

Longitud de una cadena en bash

¿Cómo obtienes la longitud de una cadena almacenada en una variable y asignas eso a otra variable?

myvar="some string"
echo ${#myvar}  
# 11

¿Cómo asignas otro variable para que tenga el valor 11?

359voto

F. Hauri Puntos 5893

Longitud de la cadena UTF-8

Además de La respuesta correcta de fedorqui Me gustaría mostrar la diferencia entre cadena longitud y byte longitud :

myvar='Généralités'
chrlen=${#myvar}
oLang=$LANG oLcAll=$LC_ALL
LANG=C LC_ALL=C
bytlen=${#myvar}
LANG=$oLang LC_ALL=$oLcAll
printf "%s is %d char len, but %d bytes len.\n" "${myvar}" $chrlen $bytlen

se rendirá:

Généralités is 11 char len, but 14 bytes len.

incluso podría echar un vistazo a los caracteres almacenados:

myvar='Généralités'
chrlen=${#myvar}
oLang=$LANG oLcAll=$LC_ALL
LANG=C LC_ALL=C
bytlen=${#myvar}
printf -v myreal "%q" "$myvar"
LANG=$oLang LC_ALL=$oLcAll
printf "%s has %d chars, %d bytes: (%s).\n" "${myvar}" $chrlen $bytlen "$myreal"

responderá:

Généralités has 11 chars, 14 bytes: ($'G\303\251n\303\251ralit\303\251s').

Nota: Según Comentario de Isabell Cowan He añadido la configuración de $LC_ALL junto con $LANG .

Longitud de un argumento, muestra de trabajo

Los argumentos funcionan igual que las variables normales

showStrLen() {
    local bytlen sreal oLang=$LANG oLcAll=$LC_ALL
    LANG=C LC_ALL=C
    bytlen=${#1}
    printf -v sreal %q "$1"
    LANG=$oLang LC_ALL=$oLcAll
    printf "String '%s' is %d bytes, but %d chars len: %s.\n" "$1" $bytlen ${#1} "$sreal"
}

funcionará como

showStrLen théorème
String 'théorème' is 10 bytes, but 8 chars len: $'th\303\251or\303\250me'

Útil printf herramienta de corrección:

Si tú:

for string in Généralités Language Théorème Février  "Left: ←" "Yin Yang ☯";do
    printf " - %-14s is %2d char length\n" "'$string'"  ${#string}
done

 - 'Généralités' is 11 char length
 - 'Language'     is  8 char length
 - 'Théorème'   is  8 char length
 - 'Février'     is  7 char length
 - 'Left: ←'    is  7 char length
 - 'Yin Yang ☯' is 10 char length

No realmente bonito ¡Salida!

Para ello, he aquí una pequeña función:

strU8DiffLen() {
    local charlen=${#1} LANG=C LC_ALL=C
    return $(( ${#1} - charlen ))
}

o escrito en una sola línea:

strU8DiffLen() { local chLen=${#1} LANG=C LC_ALL=C;return $((${#1}-chLen));}

Entonces, ahora:

for string in Généralités Language Théorème Février  "Left: ←" "Yin Yang ☯";do
    strU8DiffLen "$string"
    printf " - %-$((14+$?))s is %2d chars length, but uses %2d bytes\n" \
        "'$string'" ${#string} $((${#string}+$?))
  done 

 - 'Généralités'  is 11 chars length, but uses 14 bytes
 - 'Language'     is  8 chars length, but uses  8 bytes
 - 'Théorème'     is  8 chars length, but uses 10 bytes
 - 'Février'      is  7 chars length, but uses  8 bytes
 - 'Left: ←'      is  7 chars length, but uses  9 bytes
 - 'Yin Yang ☯'   is 10 chars length, but uses 12 bytes

Desgraciadamente, esto no es perfecto.

Pero quedaron algunos comportamientos extraños de UTF-8, como los caracteres con doble espacio, los caracteres con espacio cero, el desplazamiento inverso y otros que no pueden ser tan simples...

Echa un vistazo a diffU8test.sh o diffU8test.sh.txt para más limitaciones.

185voto

fedorqui Puntos 42938

Para obtener la longitud de una cadena almacenada en una variable, por ejemplo:

myvar="some string"
size=${#myvar} 

Para confirmar que se ha guardado correctamente, echo lo siguiente:

$ echo "$size"
11

41voto

dmatej Puntos 345

Quería el caso más simple, finalmente este es el resultado:

echo -n 'Dime la longitud de esta oración.' | wc -m;
36

26voto

atesin Puntos 293

Puedes usar:

MYSTRING="abc123"
MYLENGTH=$(printf "%s" "$MYSTRING" | wc -c)
  • wc -c o wc --bytes para contar bytes = Los caracteres Unicode se cuentan con 2, 3 o más bytes.
  • wc -m o wc --chars para contar caracteres = Los caracteres Unicode se cuentan como uno hasta que usan más bytes.

21voto

JGFMK Puntos 405

En respuesta al post que comienza:

Si deseas utilizar esto con la línea de comandos o argumentos de funciones...

con el código:

tamaño=${#1}

Puede darse el caso de que solo desees verificar si un argumento tiene longitud cero y no necesitas almacenar una variable. Creo que puedes usar este tipo de sintaxis:

if [ -z "$1" ]; then
    #argumento de longitud cero
else
    #longitud no cero
fi

Consulta GNU y wooledge para obtener una lista más completa de expresiones condicionales de Bash.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X