Go from a String to an Array of "words" in Bash

I need to go from a string to an array where each entry is each word on that string. For example, starting with:

VotePedro="Vote for Pedro"

I need the array:

Vote
For
Pedro

Which I should then be able to iterate over as:

for i in "${votePedroArray[@]}"
    do
    ## Do something
    done
Asked By: farid99

||
VotePedro="Vote for Pedro"
votePedroArray=(${VotePedro})

Explanation:

Arrays are usually declared using parentheses. For example votePedroArray=("Vote" "For" "Pedro") would give you an array of length 3. And ${VotePedro} is the same as $VotePedro in this context. To access individual array elements, you can use brackets similar to what you had for the for loop in your question. e.g. ${votePedroArray[0]} is the first element in the array (“Vote” for this example)

Answered By: airfishey

In bash and most other Bourne-like shells, when you leave a variable expansion unquoted, e.g. $VotePedro, the following steps are performed:

  1. Look up the value of the variable.
  2. Split the value at each block of whitespace into a list of strings. More generally, the separators are the characters in the value of the IFS variable; by default that’s space, tab and newline.
  3. Interpret each element of the list as a wildcard pattern; for each element, if the pattern matches some files, then replace that element by the list of matching file names.

Thus you can split a string into whitespace-delimited elements (assuming the default value of IFS) by turning off wildcard expansion and expanding a variable whose value is that string outside of quotes.

VotePedro="Vote for Pedro"
set -f
votePedroArray=($VotePedro)
set +f
for i in "${votePedroArray[@]}"; do …

You can directly do the split at the point of use; this would work even in shells such as sh that don’t have arrays:

VotePedro="Vote for Pedro"
set -f
for i in ${votePedro}; do
  set +f
  …
done
set +f

Besides breaking it on $IFS, you can also just break it on whatever you like:

set ''
while case $var in
      (* *) ;; (*)
      ! a=("$var$@")
      esac
do    set '' "${var##* }$@"
      var=${var% "$2"}
done

…which would allow for whitespace separated null-fields, even.

Answered By: mikeserv
Categories: Answers Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.