How to iterate through string one word at a time in zsh

半腔热情 提交于 2019-12-06 16:50:34

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!