如何修改以下代码,以便在zsh中运行时展开$things
并一次迭代一次?
things="one two"
for one_thing in $things; do
echo $one_thing
done
我希望输出为:
one
two
但如上所述,它输出:
one two
(我正在寻找在bash中运行上述代码时获得的行为)
答案 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
。