问题
How do I modify the following code so that when run in zsh it expands $things and iterates through them one at a time?
things="one two"
for one_thing in $things; do
echo $one_thing
done
I want the output to be:
one
two
But as written above, it outputs:
one two
(I'm looking for the behavior that you get when running the above code in bash)
回答1:
In order to see the behavior compatible with Bourne shell, you'd need to set the option SH_WORD_SPLIT:
setopt shwordsplit # this can be unset by saying: unsetopt shwordsplit
things="one two"
for one_thing in $things; do
echo $one_thing
done
would produce:
one
two
However, it's recommended to use an array for producing word splitting, e.g.,
things=(one two)
for one_thing in $things; do
echo $one_thing
done
You may also want to refer to:
3.1: Why does $var where var="foo bar" not do what I expect?
回答2:
You can use the z variable expansion flag to do word splitting on a variable
things="one two"
for one_thing in ${(z)things}; do
echo $one_thing
done
Read more about this and other variable flags in man zshexpn, under "Parameter Expansion Flags."
回答3:
You can assume the Internal Field Separator (IFS) on bash to be \x20 (space). This makes the following work:
#IFS=$'\x20'
#things=(one two) #array
things="one two" #string version
for thing in ${things[@]}
do
echo $thing
done
With this in mind you can implement this in many different ways just manipulating the IFS; even on multi-line strings.
回答4:
Another way, which is also portable between Bourne shells (sh, bash, zsh, etc.):
things="one two"
for one_thing in $(echo $things); do
echo $one_thing
done
Or, if you don't need $things defined as a variable:
for one_thing in one two; do
echo $one_thing
done
Using for x in y z will instruct the shell to loop through a list of words, y, z.
The first example uses command substitution to transform the string "one two" into a list of words, one two (no quotes).
The second example is the same thing without echo.
Here's an example that doesn't work, to understand it better:
for one_thing in "one two"; do
echo $one_thing
done
Notice the quotes. This will simply print
one two
because the quotes mean the list has a single item, one two.
来源:https://stackoverflow.com/questions/23157613/how-to-iterate-through-string-one-word-at-a-time-in-zsh