17

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

3 Answers 3

20
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)

4
  • 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, 2015 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, 2015 at 18:39
  • 1
    Thanks for your answer. I would upvote but I don't have enough reputation yet.
    – farid99
    Jul 8, 2015 at 19:02
  • 2
    And to iterate over them: for vote in ${votePedroArray[@]}; do echo $vote; done
    – Goblinhack
    Dec 15, 2017 at 20:36
5

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
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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .