web-dev-qa-db-fra.com

Longueur de la chaîne en bash

Comment obtenir la longueur d'une chaîne stockée dans une variable et l'affecter à une autre variable?

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

Comment définir une autre variable sur la sortie 11?

372
AJP

Longueur de chaîne UTF-8

En plus de réponse correcte de fedorqui , je voudrais montrer la différence entre la longueur de la chaîne et la longueur en octets:

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

rendra:

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

vous pouvez même jeter un coup d'œil aux caractères stockés:

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"

répondra:

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

Note: Selon commentaire d'Isabel Cowan , j'ai ajouté le réglage à $LC_ALL avec $LANG.

Longueur d'un argument

L'argument fonctionne de la même manière que les variables normales

strLen() {
    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"
}

travaillera comme

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

Outil de correction printf utile:

Si vous:

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

Pas vraiment joli ... Pour cela, il y a une petite fonction:

strU8DiffLen () { 
    local bytlen oLang=$LANG oLcAll=$LC_ALL
    LANG=C LC_ALL=C
    bytlen=${#1}
    LANG=$oLang LC_ALL=$oLcAll
    return $(( bytlen - ${#1} ))
}

Alors maintenant:

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

Mais il reste un comportement étrange UTF-8, comme des caractères double-espacés, des caractères zéro-espacés, un déplacement inversé et d'autres qui ne pourraient pas être aussi simples ... Regardez diffU8test.sh ou - diffU8test.sh.txt pour plus de limitations.

229
F. Hauri

Pour obtenir la longueur d'une chaîne stockée dans une variable, dites:

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

Pour confirmer qu'il a été correctement enregistré, echo le:

$ echo "$size"
11
436
fedorqui

Vous pouvez utiliser:

MYSTRING="abc123"
MYLENGTH=$(printf "%s" "$MYSTRING" | wc -c)
  • wc -c ou wc --bytes pour le nombre d'octets = Les caractères Unicode sont comptés avec 2, 3 octets ou plus.
  • wc -m ou wc --chars pour le nombre de caractères = Les caractères Unicode sont comptés individuellement jusqu'à ce qu'ils utilisent davantage d'octets.
20
atesin

Si vous souhaitez utiliser cela avec des arguments de ligne de commande ou de fonction, assurez-vous d'utiliser size=${#1} au lieu de size=${#$1}. Le second peut être plus instinctif, mais sa syntaxe est incorrecte.

15
Dick Guertin

Je voulais le cas le plus simple, enfin c'est un résultat:

echo -n 'Tell me the length of this sentence.' | wc -m;
36
13
dmatej

En réponse au poste commençant:

Si vous voulez utiliser ceci avec des arguments de ligne de commande ou de fonction ...

avec le code:

size=${#1}

Il se peut que vous souhaitiez simplement rechercher un argument de longueur nulle et ne pas avoir besoin de stocker une variable. Je crois que vous pouvez utiliser ce type de syntaxe:

if [ -z "$1" ]; then
    #zero length argument 
else
    #non-zero length
fi

Voir GNU et wooledge pour une liste plus complète des expressions conditionnelles Bash.

12
JGFMK

En utilisant votre exemple fourni

#KISS (Keep it simple stupid)
size=${#myvar}
echo $size
10
thistleknot

Voici deux manières de calculer la longueur d'une variable:

echo ${#VAR}
echo -n $VAR | wc -m
echo -n $VAR | wc -c
printf $VAR | wc -m
expr length $VAR
expr $VAR : '.*'

et pour définir le résultat dans une autre variable, assignez simplement la commande ci-dessus avec une citation en arrière dans une autre variable comme suit:

otherVar=`echo -n $VAR | wc -m`   
echo $otherVar

http://techopsbook.blogspot.in/2017/09/how-to-find-length-of-string-variable.html

9
Mukesh Shakya

J'essayais de faire quelque chose de similaire, mais je voulais juste m'assurer que la saisie de l'utilisateur n'était pas trop longue.

if [ ${#string} -ge 12 ]; then 
    echo ">= 12 characters. too long"
    exit
else 
    echo "under 12 characters, not too long."
fi
7
TrophyGeek