假设我有一个包含三个文件的文件夹:
foo1
foo2
bar
1. 如果我跑
list_of_files=$(print foo*)
echo $list_of_files
我得到:foo1 foo2
2.如果我跑
list_of_files=$(print bar*)
echo $list_of_files
我得到:bar
3.但是,如果我跑
list_of_files=$(print other*)
echo $list_of_files
我得到:(虽然zsh: no matches found: other*
变量$list_of_files
是空的)
有没有办法让 zsh 在无法匹配 glob 扩展时不抱怨?
我的目标是使用上面的机制默默收集与给定 glob 模式匹配的文件列表。
答案1
使用 glob 限定符打开null_glob
您的模式的选项N
。
list_of_files=(*(N))
如果您要对脚本或函数中的所有模式执行此操作,请打开以下null_glob
选项:
setopt null_glob
这个答案有 bash 和 ksh 等价物。
不要使用print
或命令替换!这会生成一个由文件名组成的字符串,文件名之间有空格,而不是字符串列表。 (看什么是分词?为什么它在 shell 编程中很重要?)
答案2
更好的方法:for a in *(.N); do ... ; done
. N 选项使 zsh 向 for 传递一个空列表,并且 for 将迭代零次。
留意ls *.foo(.N)
;当 ls 收到空参数列表时,它会列出所有文件,而不是不列出任何文件。这就是为什么我不喜欢 NULL_GLOB (或其 bash 等效项):它改变了全部通配符很容易中断对例如 ls 的调用。
答案3
我认为您正在寻找以下NULL_GLOB
选项:
NULL_GLOB (-G) If a pattern for filename generation has no matches, delete the pattern from the argument list instead of reporting an error. Overrides NOMATCH.
答案4
试试这个方法:
list_of_files=$(print other*) 2>/dev/null
它将错误输出从 stderr 重定向到 /dev/null 并且不会显示。