number of tokens in bash variable

前端 未结 7 2155
挽巷
挽巷 2020-12-09 08:41

how can I know the number of tokens in a bash variable (whitespace-separated tokens) - or at least, wether it is one or there are more.

相关标签:
7条回答
  • 2020-12-09 08:47

    For a robust, portable sh solution, see @JoSo's functions using set -f.

    (Simple bash-only solution for answering (only) the "Is there at least 1 whitespace?" question; note: will also match leading and trailing whitespace, unlike the awk solution below:

     [[ $v =~ [[:space:]] ]] && echo "\$v has at least 1 whitespace char."
    

    )

    Here's a robust awk-based bash solution (less efficient due to invocation of an external utility, but probably won't matter in many real-world scenarios):

    # Functions - pass in a quoted variable reference as the only argument.
    # Takes advantage of `awk` splitting each input line into individual tokens by
    # whitespace; `NF` represents the number of tokens.
    # `-v RS=$'\3'` ensures that even multiline input is treated as a single input 
    # string.
    countTokens() { awk -v RS=$'\3' '{print NF}' <<<"$1"; }
    hasMultipleTokens() { awk -v RS=$'\3' '{if(NF>1) ec=0; else ec=1; exit ec}' <<<"$1"; }
    
    # Example: Note the use of glob `*` to demonstrate that it is not 
    # accidentally expanded.
    v='I am *'
    
    echo "\$v has $(countTokens "$v") token(s)."
    
    if hasMultipleTokens "$v"; then
      echo "\$v has multiple tokens."
    else
      echo "\$v has just 1 token."
    fi
    
    0 讨论(0)
  • 2020-12-09 08:51

    I can't understand why people are using those overcomplicated bashisms all the time. There's almost always a straight-forward, no-bashism solution.

    howmany() { echo $#; }
    myvar="I am your var"
    howmany $myvar
    

    This uses the tokenizer built-in to the shell, so there's no discrepancy.

    Here's one related gotcha:

    myvar='*'
    echo $myvar
    echo "$myvar"
    set -f
    echo $myvar
    echo "$myvar"
    

    Note that the solution from @guns using bash array has the same gotcha.

    The following is a (supposedly) super-robust version to work around the gotcha:

    howmany() ( set -f; set -- $1; echo $# )
    

    If we want to avoid the subshell, things start to get ugly

    howmany() {
        case $- in *f*) set -- $1;; *) set -f; set -- $1; set +f;; esac
        echo $#
    }
    

    These two must be used WITH quotes, e.g. howmany "one two three" returns 3

    0 讨论(0)
  • 2020-12-09 08:54

    The $# expansion will tell you the number of elements in a variable / array. If you're working with a bash version greater than 2.05 or so you can:

    VAR='some string with words'
    VAR=( $VAR )
    echo ${#VAR[@]}
    

    This effectively splits the string into an array along whitespace (which is the default delimiter), and then counts the members of the array.

    EDIT:

    Of course, this recasts the variable as an array. If you don't want that, use a different variable name or recast the variable back into a string:

    VAR="${VAR[*]}"
    
    0 讨论(0)
  • 2020-12-09 08:54

    Simple method:

    $ VAR="a b c d"
    $ set $VAR
    $ echo $#
    4
    
    0 讨论(0)
  • 2020-12-09 09:02

    To count:

    sentence="This is a sentence, please count the words in me."
    words="${sentence//[^\ ]} "
    echo ${#words}
    

    To check:

    sentence1="Two words"
    sentence2="One"
    [[ "$sentence1" =~ [\ ] ]] && echo "sentence1 has more than one word"
    [[ "$sentence2" =~ [\ ] ]] && echo "sentence2 has more than one word"
    
    0 讨论(0)
  • 2020-12-09 09:05
    set VAR='hello world'
    echo $VAR | wc -w
    

    here is how you can check.

    if [ `echo $VAR | wc -w` -gt 1 ] 
    then
        echo "Hello"
    fi
    
    0 讨论(0)
提交回复
热议问题