在 zsh 中列出带有空格的元素

Fel*_*lix 10 shell scripting zsh

在这一点上,我一直在研究 zsh 脚本编写 2 个小时,但我已经碰壁了。我想查看可能有空格的文件列表。我愿意接受与以下示例完全不同的方法,只要它们是 zsh,因为 zsh 是我正在研究的内容,而不是我尝试编写脚本的任务。

files=(`ls`)
for f in $files; do
    print $f
done
Run Code Online (Sandbox Code Playgroud)

我显然不仅仅是重新创建ls,我只想$f捕获循环的每次迭代的整个文件名。

Gil*_*il' 12

首先,我假设使用ls只是一个例子。您无法解析ls任何 shell 中的输出,因为它是不明确的。如果这对您来说是新闻,请阅读为什么您不应该解析 ls(1) 的输出。在任何 shell 中,要获取文件列表,请使用通配符,例如files=(*).

在 zsh 中,就像在其他 shell 中一样,命令替换的结果被拆分为空格字符处的单词(更准确地说,根据 的值IFS)。(与其他 shell 不同,命令替换的结果在 zsh 中不受 globbing 的影响。)所以如果ls命令的输出是

hello world
wibble
Run Code Online (Sandbox Code Playgroud)

然后files=($(ls))files数组设置为包含 3 个元素:hello,worldwibble

如果命令替换在双引号中,则不执行拆分。您可以使用参数扩展标志执行自定义拆分。使用@标志表示拆分的结果是一个数组(奇怪的是,您需要将扩展​​保留在双引号中,即"${(@)…}",即使双引号字符串将扩展为多个单词)。对于分割,使用s标志,例如"${(@s:,:)…}"在逗号处分割;该f标志处分割仅换行。

files=("${(@f)$(ls)}")
Run Code Online (Sandbox Code Playgroud)

请注意,通常迭代数组的正确方法是for f in $files[@],$files剥离空元素(在这里,这无关紧要,因为元素不会为空)。

print $f$f如果以 a 开头并在 中-扩展反斜杠,则解释为开关$f。使用print -r -- $f, 或者print -rn -- $f如果您不想在字符串后添加换行符。