如何在zsh中一次遍历字符串一个单词

时间:2014-04-18 15:52:52

标签: bash while-loop zsh expansion

如何修改以下代码,以便在zsh中运行时展开$things并一次迭代一次?

things="one two"

for one_thing in $things; do
    echo $one_thing
done

我希望输出为:

one 
two

但如上所述,它输出:

one two

(我正在寻找在bash中运行上述代码时获得的行为)

4 个答案:

答案 0 :(得分:38)

为了查看与Bourne shell兼容的行为,您需要设置选项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

会产生:

one
two

但是,建议使用数组来产生分词,例如

things=(one two)

for one_thing in $things; do
    echo $one_thing
done

您可能还想参考:

3.1: Why does $var where var="foo bar" not do what I expect?

答案 1 :(得分:6)

您可以使用z变量扩展标志对变量进行分词

things="one two"

for one_thing in ${(z)things}; do
    echo $one_thing
done

在“参数扩展标志”下的man zshexpn中阅读有关此变量标志和其他变量标志的更多信息。

答案 2 :(得分:3)

您可以假设bash上的内部字段分隔符(IFS)为\ x20(空格)。这使得以下工作:

#IFS=$'\x20'
#things=(one two) #array
things="one two"  #string version

for thing in ${things[@]}
do
   echo $thing
done

考虑到这一点,您可以通过多种方式实现它,只需操作IFS即可;甚至在多行字符串上也是如此。

答案 3 :(得分:1)

另一种方法,也可以在Bourne外壳(sh,bash,zsh等)之间移植:

things="one two"

for one_thing in $(echo $things); do
    echo $one_thing
done

或者,如果不需要将$things定义为变量:

for one_thing in one two; do
    echo $one_thing
done

使用for x in y z将指示shell遍历单词列表y, z

第一个示例使用command substitution将字符串"one two"转换为单词列表one two(不带引号)。

第二个例子是没有echo的情况。

为了更好地理解,以下示例无效:

for one_thing in "one two"; do
    echo $one_thing
done

注意引号。这将简单地打印

one two

因为引号表示列表中只有一个项one two