593 Stimmen

Länge des Strings in bash

Wie erhalten Sie die Länge eines in einer Variablen gespeicherten Strings und weisen dies einer anderen Variable zu?

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

Wie weisen Sie einer anderen Variable den Wert 11 zu?

644voto

fedorqui Punkte 249453

Um die Länge eines in einer Variable gespeicherten Strings zu erhalten, sagen Sie:

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

Um zu bestätigen, dass es ordnungsgemäß gespeichert wurde, echo es:

$ echo "$size"
11

370voto

F. Hauri Punkte 57640

Bearbeiten 2023-02-13: Verwendung von printf %n anstelle von Lokalisierungen...

UTF-8 Zeichenfolgenlänge

Zusätzlich zu fedorquis richtiger Antwort möchte ich den Unterschied zwischen Zeichenfolgenlänge und Byte-Länge zeigen:

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 hat %d Zeichenlänge, aber %d Byte-Länge.\n" "${myvar}" $chrlen $bytlen

wird anzeigen:

Généralités hat 11 Zeichenlänge, aber 14 Byte-Länge.

Sie könnten sogar die gespeicherten Zeichen betrachten:

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 hat %d Zeichen, %d Bytes: (%s).\n" "${myvar}" $chrlen $bytlen "$myreal"

wird antworten:

Généralités hat 11 Zeichen, 14 Bytes: ($'G\303\251n\303\251ralit\303\251s').

Nota: Gemäß dem Kommentar von Isabell Cowan habe ich Einstellungen zu $LC_ALL zusammen mit $LANG hinzugefügt.

Gleiches, aber ohne mit Lokalisierungen spielen zu müssen

Ich habe kürzlich das %n -Format des printf-Befehls (eingebaut) gelernt:

myvar='Généralités'
chrlen=${#myvar}
printf -v _ %s%n "$myvar" bytlen
printf "%s hat %d Zeichenlänge, aber %d Byte-Länge.\n" "${myvar}" $chrlen $bytlen
Généralités hat 11 Zeichenlänge, aber 14 Byte-Länge.

Die Syntax ist etwas gegenintuitiv, aber das ist sehr effizient! (Die weitere Funktion strU8DiffLen ist etwa 2 Mal schneller, wenn printf anstelle der vorherigen Version mit lokale LANG=C verwendet wird.)

Länge eines Arguments, Arbeitsbeispiel

Argumente funktionieren genauso wie reguläre Variablen

showStrLen() {
    local -i chrlen=${#1} bytlen
    printf -v _ %s%n "$1" bytlen
    LANG=$oLang LC_ALL=$oLcAll
    printf "Zeichenfolge '%s' hat %d Bytes, aber eine Länge von %d Zeichen: %q.\n" "$1" $bytlen $chrlen "$1"
}

wird funktionieren wie

showStrLen théorème
Zeichenfolge 'théorème' hat 10 Bytes, aber eine Länge von 8 Zeichen: $'th\303\251or\303\250me'

Nützliches printf-Korrekturwerkzeug:

Wenn Sie:

für string in Généralités Language Théorème Février  "Links: " "Yin Yang ";do
    printf " - %-14s hat %2d Zeichenlänge\n" "'$string'"  ${#string}
done

 - 'Généralités' hat 11 Zeichenlänge
 - 'Language'     hat  8 Zeichenlänge
 - 'Théorème'   hat  8 Zeichenlänge
 - 'Février'     hat  7 Zeichenlänge
 - 'Links: '    hat  7 Zeichenlänge
 - 'Yin Yang ' hat 10 Zeichenlänge

Nicht wirklich schöne Ausgabe!

Dafür gibt es eine kleine Funktion:

strU8DiffLen() {
    local -i bytlen
    printf -v _ %s%n "$1" bytlen
    return $(( bytlen - ${#1} ))
}

oder in einer Zeile geschrieben:

strU8DiffLen() { local -i _bl;printf -v _ %s%n "$1" _bl;return $((_bl-${#1}));}

Dann jetzt:

für string in Généralités Language Théorème Février  "Links: " "Yin Yang ";do
    strU8DiffLen "$string"
    printf " - %-$((14+$?))s hat %2d Zeichenlänge, verwendet jedoch %2d Bytes\n" \
        "'$string'" ${#string} $((${#string}+$?))
  done 

 - 'Généralités'  hat 11 Zeichenlänge, verwendet jedoch 14 Bytes
 - 'Language'     hat  8 Zeichenlänge, verwendet jedoch  8 Bytes
 - 'Théorème'     hat  8 Zeichenlänge, verwendet jedoch 10 Bytes
 - 'Février'      hat  7 Zeichenlänge, verwendet jedoch  8 Bytes
 - 'Links: '      hat  7 Zeichenlänge, verwendet jedoch  9 Bytes
 - 'Yin Yang '   hat 10 Zeichenlänge, verwendet jedoch 12 Bytes

Leider ist dies nicht perfekt!

Aber es gibt noch einige seltsame UTF-8-Verhaltensweisen, wie doppelte Leerzeichen, null Leerzeichen, umgekehrte Verschiebungen und andere, die nicht so einfach sein könnten...

Schauen Sie sich diffU8test.sh oder diffU8test.sh.txt für weitere Einschränkungen an.

44voto

dmatej Punkte 1389

Ich wollte den einfachsten Fall, schließlich ist dies das Ergebnis:

echo -n 'Sagen Sie mir die Länge dieses Satzes.' | wc -m;
36

27voto

atesin Punkte 303

Sie können verwenden:

MYSTRING="abc123"
MYLENGTH=$(printf "%s" "$MYSTRING" | wc -c)
  • wc -c oder wc --bytes für Byte-Zählung = Unicode-Zeichen werden mit 2, 3 oder mehr Bytes gezählt.
  • wc -m oder wc --chars für Zeichen-Zählung = Unicode-Zeichen werden einzeln gezählt, bis sie mehr Bytes verwenden.

23voto

JGFMK Punkte 7643

Als Antwort auf den Beitrag, der so beginnt:

Wenn Sie dies mit Befehlszeile oder Funktionsargumenten verwenden möchten...

mit dem Code:

size=${#1}

Es könnte der Fall sein, dass Sie nur nach einem Argument mit null Länge prüfen möchten und keine Notwendigkeit haben, eine Variable zu speichern. Ich glaube, Sie können diese Art von Syntax verwenden:

if [ -z "$1" ]; then
    # Argument mit null Länge
else
    # Argument mit nicht null Länge
fi

Siehe GNU und wooledge für eine umfassendere Liste von Bash-Bedingungsausdrücken.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X