0

I am trying to count the seize of an parameter without the numbers and spaces, like if someone types in "Hello player1" it has to echo "11 characters". I have tried using ${#value} but this counts numbers and spaces.

    if [ -z "$1" ]
    then
        echo "write at least 1 word"
else
    for value in "$@" 
        do
            echo "${value//[[:digit:]]/}"
            
    done
    echo ${#value}
fi

The result of the code

as you can see in the image it counts only the last parameter and counts the numbers what I don't want

Results of the second code

1 Answers1

4

Break it into two steps.

set -- "abc 123" "d12"
for value do  # in "$@" is default, don't need to say it
  valueTrimmed=${value//[[:digit:][:space:]]/}
  echo "The string '$value' has ${#valueTrimmed} valid characters"
done

...properly emits as output:

The string 'abc 123' has 3 valid characters
The string 'd12' has 1 valid characters

bash does not support nesting parameter expansions; you cannot do this in one step as a shell builtin (it could be done in a pipeline, but only with an unreasonably high performance cost).

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Thx that works but it only counts the second parameter and not the first one – kemal ozdogan Mar 18 '21 at 16:56
  • I don't understand what you mean. What "second parameter"? See the sample output now given -- we're passing in two parameters (`abc 123` and `d12`), and they both get processed. – Charles Duffy Mar 18 '21 at 16:57
  • If I type like hallo user, it only counts user. and not hallo – kemal ozdogan Mar 18 '21 at 16:58
  • That's not true. See https://ideone.com/QUVzK5 -- it properly counts `hallo user` as 9 characters. – Charles Duffy Mar 18 '21 at 17:00
  • ...why don't you show how you're doing the input? I suspect there's code you aren't showing us where the quoting is wrong. – Charles Duffy Mar 18 '21 at 17:01
  • @kemalozdogan, note that in your original code, you put `echo ${value}` **after** the loop is finished, which causes it to only operate on the last item, instead of putting it inside the loop itself. My answer here doesn't have that bug. (Also, it should be `echo "$value"` -- you don't need curly braces for the code to be correct, but you *do* need the quotes to avoid bugs; try what happens if the user enters `hello * world`). – Charles Duffy Mar 18 '21 at 17:03
  • 2
    @0stone0, re: the pipeline approach, try benchmarking it over 1000 or 10,000 items. It's _really_ slow in comparison to using native bash string operations. – Charles Duffy Mar 18 '21 at 17:05
  • https://i.stack.imgur.com/qVZE8.png here is a foto of my code and results – kemal ozdogan Mar 18 '21 at 17:13
  • I am using command line arguments as input – kemal ozdogan Mar 18 '21 at 17:16
  • @kemalozdogan, yes, but _how_ you're passing things on the command line matters. `./yourprogram hallo user` is not at all the same thing as `./yourprogram "hallo user"`, and `"$@"` only makes sense if what you're doing is the latter. – Charles Duffy Mar 18 '21 at 17:18
  • 1
    @kemalozdogan, I do not, will not, and refuse to follow links to images of code. See [Why not upload images of code/errors when asking a question?](https://meta.stackoverflow.com/a/285557/14122) on [meta]. Edit that transcript **as text** into your question. – Charles Duffy Mar 18 '21 at 17:18