如何在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 中运行上述代码时得到的行为)

【问题讨论】:

这是否意味着当zshfor 循环的列表时,$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中一次遍历一个单词的主要内容,如果未能解决你的问题,请参考以下文章

在反应jsx中一次遍历一个数组

在 node.js 中一次遍历一个包含 50 个项目的数组

如何在 Flutter 中一次只在屏幕上显示一个表单域?

如何在 C# 中一次播放多个声音

如何在 Eclipse 中一次显示 100 多个任务 //TODO?

如何在 Firestore 中一次创建/更新多个文档