Comment obtenir la longueur d'une chaîne de caractères stockée dans une variable et l'affecter à une autre variable ?
myvar="some string"
echo ${#myvar}
# 11
Comment définir une autre variable à la sortie 11
?
Comment obtenir la longueur d'une chaîne de caractères stockée dans une variable et l'affecter à une autre variable ?
myvar="some string"
echo ${#myvar}
# 11
Comment définir une autre variable à la sortie 11
?
Avec les chaînes UTF-8, vous pourriez avoir une longueur de chaîne de caractères et une longueur d'octets. voir ma réponse
Vous pouvez également l'utiliser directement dans d'autres expansions de paramètres - par exemple dans ce test je vérifie que $rulename
commence par le $RULE_PREFIX
préfixe : [ "${rulename:0:${#RULE_PREFIX}}" == "$RULE_PREFIX" ]
En plus de La réponse correcte de fedorqui Je voudrais montrer la différence entre chaîne de caractères longueur et octet longueur :
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 pourriez même jeter un coup d'oeil 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').
Nota : Selon Commentaire d'Isabell Cowan J'ai ajouté un paramètre à $LC_ALL
ainsi que $LANG
.
Les arguments fonctionnent comme les variables ordinaires
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"
}
fonctionnera comme
showStrLen théorème
String 'théorème' is 10 bytes, but 8 chars len: $'th\303\251or\303\250me'
printf
outil de correction :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 sortie !
Pour cela, voici une petite fonction :
strU8DiffLen() {
local charlen=${#1} LANG=C LC_ALL=C
return $(( ${#1} - charlen ))
}
ou écrit en une seule ligne :
strU8DiffLen() { local chLen=${#1} LANG=C LC_ALL=C;return $((${#1}-chLen));}
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 restait quelques comportements étranges de l'UTF-8, comme les caractères à double espacement, les caractères à espacement nul, le déplacement inverse et d'autres qui ne pouvaient pas être aussi simples...
Jetez un coup d'œil à diffU8test.sh o diffU8test.sh.txt pour plus de limitations.
J'apprécie cette réponse, car les systèmes de fichiers imposent des limitations de noms en octets et non en caractères.
@IsabellCowan Dans quel cas ? Je pense que non ! Vous pourriez préférer utiliser LC_ALL
mais s'il n'est pas utilisé, ce n'est pas nécessaire . Mais aucune autre variable ne doit être utilisée.
Désolé mon pote :( C'est Bash... le marteau maudit qui voit tout comme un clou, particulièrement votre pouce. "Dites-moi la longueur de cette phrase." contient 36 caractères. echo '' | wc -m
=> 1
. Vous devez utiliser -n
: echo -n '' | wc -m
=> 0
... dans ce cas, c'est une bonne solution :)
Vous pouvez utiliser :
MYSTRING="abc123"
MYLENGTH=$(printf "%s" "$MYSTRING" | wc -c)
wc -c
o wc --bytes
pour les comptes d'octets = les caractères Unicode sont comptés avec 2, 3 ou plus d'octets.wc -m
o wc --chars
pour le nombre de caractères = les caractères Unicode sont comptés individuellement jusqu'à ce qu'ils utilisent plus d'octets.
-c pour les octets. -m est pour les caractères. gnu.org/software/coreutils/manual/html_node/wc-invocation.html pubs.opengroup.org/onlinepubs/009604499/utilités/wc.html
Sérieusement ? un tuyau, un sous-shell et une commande externe pour quelque chose d'aussi trivial ?
Cela gère quelque chose comme mylen=$(printf "%s" "$HOME/.ssh" | wc -c)
alors que la solution acceptée échoue et que vous devez myvar=$HOME/.ssh
d'abord.
En réponse au post de départ :
Si vous voulez l'utiliser avec des arguments de ligne de commande ou de fonction...
avec le code :
size=${#1}
Il peut arriver que vous souhaitiez simplement vérifier si un argument est de longueur nulle et que vous n'ayez pas besoin de stocker une variable. Je crois que vous pouvez utiliser ce genre de syntaxe :
if [ -z "$1" ]; then
#zero length argument
else
#non-zero length
fi
Voir GNU y wooledge pour une liste plus complète des expressions conditionnelles Bash.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.