11

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
10
VotePedro="Vote for Pedro"
votePedroArray=(${VotePedro})
  • Could you explain what the parentheses and the brackets do? I'm new to BASH and want to understand why this would work. – farid99 Jul 8 '15 at 18:35
  • 1
    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) – airfishey Jul 8 '15 at 18:39
  • Thanks for your answer. I would upvote but I don't have enough reputation yet. – farid99 Jul 8 '15 at 19:02
  • 2
    And to iterate over them: for vote in ${votePedroArray[@]}; do echo $vote; done – Neil McGill Dec 15 '17 at 20:36
4

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
0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.