在 zsh 终端中,我想要
ls
所有视频文件,即所有以 .mp4 或 .mkv 或 .avi 或 .mov 结尾的文件(例如)。
当我执行
ls *.mp4 *.mkv *.avi *.mov
时,它会执行我想要的操作,除了如果没有具有一个或多个给定扩展名的文件。
例如如果没有 .avi 文件,上面的命令不会列出任何其他文件,而只会显示:
ls: *.avi: 没有这样的文件或目录
我注意到在 bash 而不是 zsh 中,它也给出了这个错误,但仍然显示确实存在的文件。
我认为这与通配符匹配/通配符在 zsh 和 bash 环境中工作方式的差异有关。
有没有办法只
ls
所有具有一堆给定扩展名(或其他通配符模式)的文件,无论它们是否全部出现?
您需要不止一行代码才能完成此操作。
您可以简单地使用 null glob 标志来消除错误消息,即
ls *.mp4(N) *.mkv(N)
但是,这样做的问题是,如果某个模式随后没有生成匹配的文件,则会导致它恰好扩展为 0 个路径。
如果没有
mp4
文件,但至少有一个 mkv
文件,那就没问题。然后你的命令行将被简单地解释为
ls file.mkv
但是,如果既没有
mp4
也没有 mkv
文件,则命令行将被解释为
ls
它将向您显示工作目录中所有文件的列表。
也许这对于交互式工作来说已经足够了。如果您在脚本中执行此操作,更好的方法是首先将所有匹配文件加载到数组中,然后测试数组是否为空:
files=( *.mp4(N) *.mkv(N) )
if (( $#files[@] )); then
ls $files[@]
else
print 'No mp4 or mkv files`
fi
Zsh 有几个 shell 选项,您可以更改以修改此行为:
% unsetopt nomatch # If a pattern has no matches, pass it thru unmodified.
% ls *.mp4 *.mkv *.avi *.mov
ls: *.avi: No such file or directory
ls: *.mkv: No such file or directory
ls: *.mov: No such file or directory
ls: *.mp4: No such file or directory
% setopt nullglob # If a pattern has no matches, simply remove it.
% ls *.mp4 *.mkv *.avi *.mov
%