到目前为止,我已经学习 zsh 脚本了 2 个小时,但我遇到了困难。我想浏览其中可能包含空格的文件列表。我愿意接受与以下示例完全不同的方法,只要它们是 zsh,因为 zsh 是我正在研究的内容,而不是我正在尝试编写脚本的任务。
files=(`ls`)
for f in $files; do
print $f
done
显然我不仅仅是重新创建ls
,我只是想$f
在循环的每次迭代中捕获整个文件名。
答案1
首先,我假设使用ls
只是一个例子。您无法ls
在任何 shell 中解析 的输出,因为它是不明确的。读为什么不应该解析 ls(1) 的输出如果这对你来说是新闻。在任何 shell 中,要获取文件列表,请使用通配符,例如files=(*)
.
在 zsh 中,与其他 shell 一样,结果是命令替换在空白字符处分割成单词(更准确地说,根据 的值IFS
)。 (与其他 shell 不同,命令替换的结果不受 zsh 中的通配影响。)因此,如果命令的输出ls
是
hello world
wibble
然后将数组files=($(ls))
设置files
为包含 3 个元素:hello
、world
和wibble
。
如果命令替换用双引号引起来,则不执行拆分。您可以执行自定义拆分参数扩展标志。使用该@
标志来指示拆分的结果是一个数组(奇怪的是,您需要将扩展保留在双引号中,即"${(@)…}"
,即使双引号字符串将扩展为多个单词)。对于分割,请使用s
标志,例如"${(@s:,:)…}"
以逗号分割;该f
标志仅在换行符处分割。
files=("${(@f)$(ls)}")
请注意,通常迭代数组的正确方法是for f in $files[@]
删除$files
空元素(在这里,这并不重要,因为元素不会为空)。
print $f
如果它以 a 开头并在 中展开反斜杠,则解释$f
为开关。如果您不想在字符串后添加换行符,请使用, 或者。-
$f
print -r -- $f
print -rn -- $f
答案2
在 zsh 中,您可以使用 shell 的扩展,默认情况下不执行分词。尝试
for f in /path/to/files/*; do
print ${f}
done