如何在zsh中一次遍历一个单词
Posted
技术标签:
【中文标题】如何在zsh中一次遍历一个单词【英文标题】:How to iterate through string one word at a time in zsh 【发布时间】:2014-06-03 04:03:54 【问题描述】:如何修改以下代码,以便在 zsh 中运行时扩展 $things
并一次遍历它们?
things="one two"
for one_thing in $things; do
echo $one_thing
done
我希望输出是:
one
two
但如上所述,它输出:
one two
(我正在寻找您在 bash 中运行上述代码时得到的行为)
【问题讨论】:
这是否意味着当zsh
是for
循环的列表时,$things
不是分词?它是否只进入循环体一次?回答,通过配置脚本战斗后,是“是”。从可用的 shell 列表中划掉zsh
;这太像非POSIX-shell了。我什至懒得开始思考如何配置它以“正常”工作。
你可能不喜欢它,但这种行为完全符合 POSIX,据我所知,这是 sh shell 的预期行为。
【参考方案1】:
为了查看与 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?
【讨论】:
除了全局设置shwordsplit
之外,您还可以使用$=things
为单个参数启用sh
风格的分词(当然是使用IFS
)。
@chepner,那会是什么样子?我尝试了IFS=' '; for one_thing in $=things; do
,但得到了bad substitution
错误
@RobBednark 为什么不使用数组?
应该是for one_thing in $=things; do
。您使用的是哪个版本的zsh
?在 4.3.10 中为我工作。不过,数组是一个更好的主意,因为您不必依赖使用任何单个项目中都不存在的字符串分隔符。
@chepner,我使用的是 zsh 5.0.2 (x86_64-apple-darwin13.0)【参考方案2】:
您可以使用z
变量扩展标志对变量进行分词
things="one two"
for one_thing in $(z)things; do
echo $one_thing
done
在“参数扩展标志”下的 man zshexpn
中了解有关此变量标志和其他变量标志的更多信息。
【讨论】:
【参考方案3】:您可以假设 bash 上的内部字段分隔符 (IFS) 为 \x20(空格)。这使得以下工作:
#IFS=$'\x20'
#things=(one two) #array
things="one two" #string version
for thing in $things[@]
do
echo $thing
done
考虑到这一点,您可以通过多种不同的方式实现这一点,只需操纵 IFS;即使是多行字符串。
【讨论】:
【参考方案4】:另一种方式,也可以在 Bourne shell(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
。
【讨论】:
以上是关于如何在zsh中一次遍历一个单词的主要内容,如果未能解决你的问题,请参考以下文章