【问题标题】:Loop over space-separated string in zsh在 zsh 中循环以空格分隔的字符串
【发布时间】:2021-10-26 00:34:03
【问题描述】:

zsh中什么控制环境知道按空格分割?

我确信这很简单,但在我所有的搜索中还没有弄清楚是什么控制了它。

尝试循环遍历以空格分隔的字符串中的项目,如下所示:

s='foo bar baz'
for i in $s; do
  echo "$i END"
done
# foo bar baz END

# ---

s='foo bar baz'
a=( $s )
echo ${a[0]} # (empty)
echo ${a[1]} # foo bar baz

# ---

s='foo bar baz'
IFS=' ' read a <<< $s
for i in "${a[@]}"; do
  echo "$i END"
done
# foo bar baz END

不同的方法通过shbash 工作,但在oh-my-zsh 的shell 中我无法用空格分隔,得到上面的结果。可能不是oh-my-zsh - 但希望了解是什么推动了这一点。

来自 bash 的工作示例:

s='foo bar baz'
for i in $s; do
  echo "$i END"
done
# foo END
# bar END
# baz END

【问题讨论】:

  • 您是否在询问 zsh 分词行为,以及它与 Bash / POSIX sh 上的分词行为有何不同/为何不同?
  • oh-my-zsh 只是一个自定义zsh shell 的框架;如果您使用的是oh-my-zsh,那么您使用的是zsh(不是bash)。 zsh 与大多数其他 shell 显着不同,因此您需要查找有关 zsh 的文档,而不是 bash 或任何其他 shell(更不用说 oh-my-zsh,因为这只是一种自定义 @ 987654336@).
  • @BenjaminW。 - 是的,以及如何让 zsh 按字分割。

标签: bash sh zsh oh-my-zsh


【解决方案1】:

Zsh 和 bash 是两种不同的编程语言。它们相似,但不完全相同。在 bash 中,更一般地,在 Bourne 样式的 shell(shdashksh,...)中,未加引号的变量扩展 $foo 执行以下操作:

  1. 取变量foo的值,它是一个字符串。 (如果没有变量foo,则取空字符串。)
  2. 将字符串拆分为空格分隔的部分。 (更一般地说,IFS 变量的值决定了字符串的拆分方式;这里我不会详细介绍。)结果是字符串列表。
  3. 对于列表中的每个元素,如果它是一个通配符模式,即如果它包含至少一个通配符*?\[(可能更多,取决于某些shell选项),并且该模式至少匹配一个文件名,然后该元素被匹配的文件名列表替换。不包含任何通配符的元素,以及包含通配符但不匹配任何文件名的元素,将被单独保留。结果又是一个字符串列表。

Zsh 主要是一个 Bourne 风格的 shell,但它有一些区别,这是主要的:$foo 具有以下更简单的行为。

  1. 取变量foo的值,它是一个字符串。 (如果没有变量foo,则取空字符串。)
  2. 如果这导致一个空词,则该词被删除。 (例如,$foo$bar 只有在 foobar 都为空或未设置时才会被消除。)

请注意,在 sh 或 bash 中,$foo 仅适用于不包含任何通配符或使用 set -f 禁用通配符的字符串。

在zsh中在空白处分割字符串,有两种简单的方法:

这与 oh-my-zsh 无关,它是一个用于配置 zsh 以进行交互使用的插件。

【讨论】:

  • 您还可以在单​​个脚本中使用 setopt sh_word_split 启用不带引号的扩展的分词。
  • @Shawn 是的,但这会影响每个参数扩展。几乎没有任何理由显式启用此选项:如果您需要 bash/sh/ksh 兼容性,请使用 emulate
  • @Gilles'SO-stopbeingevil' 我认为这与 oh-my-zsh 无关,但可能是 zsh - 提到了 OMZ,因为它有自以为是的设置,但可能应该单独提及。即使有这种解释,在FOR - IN 循环之前设置 IFS 也不会执行任何操作,并且参数标志扩展 (foo='bar baz'; ${(p: :)foo};) 会给出错误“zsh:标志错误”。但是,设置 setopt sh_word_split 可以。我将研究这个设置是什么以及为什么它默认不同。
  • 你们都把我引向了我正在寻找的东西 - zsh 的默认值不会对未引用的参数扩展进行分词 - stackoverflow.com/a/6715447/9404093。不知道我在浏览手册时是怎么错过的。
  • 虽然这回答了您提出的问题,但几乎可以肯定的是,您实际上想要代替这些建议的是使用数组。这也适用于 bash 或 ksh 脚本。只有在没有数组的 sh 中,自动分词是一个理想的功能,但它使得脚本不中断变得更加困难,例如文件名包含空格。
猜你喜欢
  • 2012-04-19
  • 1970-01-01
  • 2010-12-01
  • 2018-09-25
  • 2014-05-02
  • 2014-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多