如何从不匹配的全局模式中静默获取空字符串

如何从不匹配的全局模式中静默获取空字符串

假设我有一个包含三个文件的文件夹:

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 并且不会显示。

相关内容