Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Length of string in bash

How do you get the length of a string stored in a variable and assign that to another variable?

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

How do you set another variable to the output 11?

like image 944
AJP Avatar asked Jun 28 '13 15:06

AJP


People also ask

How do I find the length of a string in Linux?

Another way to count the length of a string is to use `expr` command with length keyword. The following commands will assign a value to the variable, $string, store the length value to the variable, $len and print the value of $len. Output: The following output will appear after running the above command.

What does [- Z $1 mean in bash?

$1 means an input argument and -z means non-defined or empty. You're testing whether an input argument to the script was defined when running the script.

What does =~ mean in bash?

A regular expression matching sign, the =~ operator, is used to identify regular expressions. Perl has a similar operator for regular expression corresponding, which stimulated this operator.


2 Answers

To get the length of a string stored in a variable, say:

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

To confirm it was properly saved, echo it:

$ echo "$size" 11 
like image 67
fedorqui 'SO stop harming' Avatar answered Oct 16 '22 08:10

fedorqui 'SO stop harming'


UTF-8 string length

In addition to fedorqui's correct answer, I would like to show the difference between string length and byte length:

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 

will render:

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

you could even have a look at stored chars:

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" 

will answer:

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

Nota: According to Isabell Cowan's comment, I've added setting to $LC_ALL along with $LANG.

Length of an argument, working sample

Argument work same as regular variables

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" } 

will work as

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

Useful printf correction tool:

If you:

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 

Not really pretty output!

For this, here is a little function:

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

or written in one line:

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

Then now:

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 

Unfortunely, this is not perfect!

But there left some strange UTF-8 behaviour, like double-spaced chars, zero spaced chars, reverse deplacement and other that could not be as simple...

Have a look at diffU8test.sh or diffU8test.sh.txt for more limitations.

like image 42
F. Hauri Avatar answered Oct 16 '22 10:10

F. Hauri