ls忽略“没有匹配项”


8

我想列出的所有文件的文件夹,名为中foldername有扩展testatestbtest

我立即想到要跑步 ls ./foldername/*.{a,b,}test

除非扩展名没有任何内容,否则此方法工作正常atest,在这种情况下,我会收到错误消息zsh: no matches found: ./foldername/*.atest

有什么方法可以简单地忽略此错误并打印确实存在的文件?

我需要在ZSH和BASH中都可以使用。


3
将标准错误重定向到/dev/null
DopeGhoti

Answers:


9

最好这样做find

find ./foldername -maxdepth 1 -name '*.atest' -o -name '*.btest' -o -name '*.test'

1
也许带有-maxdepth 1,以更接近地模仿ls行为
Jeff Schaller

4
@JeffSchaller,请注意,这-maxdepth是一个GNU扩展。注3个与水珠其他方面的差异:find将包括隐藏文件,不排序列表并不能匹配包含字节不是(像形成有效字符的文件名$'St\xe9phane.atest'中使用UTF-8)
斯特凡Chazelas

11

ls -d ./foldername/*.{a,b,}test

{a,b,...} 不是全局运算符,而是括号扩展,首先扩展为:

ls -d ./foldername/*.atest ./foldername/*.btest ./foldername/*.test

每个glob都会单独扩展,如果有任何glob不匹配,则会按您期望的那样取消该命令zsh(或fish;中的bash;您需要failglob获得类似行为的选项)。

在这里,您只想使用一个与所有这些文件都匹配的glob,并且仅在该glob与任何文件都不匹配时才取消命令:

ls -d ./foldername/*.(a|b|)test

您不想使用nullglob,就像没有任何glob匹配一样,它会在ls没有参数的情况下运行,因此请列出当前目录。cshnullglob在这方面更好,因为它除去了不匹配的glob,但如果所有glob都不匹配,仍会取消命令。

您不想使用nonomatch,因为那样会给您破坏行为的感觉,bash这是一个耻辱。

对于在zsh和中bash均可使用的glob替代方案,您可以使用ksh glob (set -o kshglobin zshshopt -s extglobin bash)。

然后,您将执行以下操作:

ls -d ./foldername/*.@(a|b|)test

要么:

ls -d ./foldername/*.?([ab])test

在中添加failglob选项,bash以避免在ls不匹配时将字面量直接传递给它。

请参见为什么nullglob不是默认值?欲获得更多信息。


我不确定为什么这是OP的要求,但是在bash和zsh中都可以使用extglob吗?我不得不使用?(...)+(...)bash。
杰夫·谢勒

@JeffSchaller,看到编辑
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.