zsh ls:查找多个扩展名,如果某些扩展名不存在则不会出错

问题描述 投票:0回答:2

在 zsh 终端中,我想要

ls
所有视频文件,即所有以 .mp4 或 .mkv 或 .avi 或 .mov 结尾的文件(例如)。

当我执行

ls *.mp4 *.mkv *.avi *.mov
时,它会执行我想要的操作,除了如果没有具有一个或多个给定扩展名的文件。

例如如果没有 .avi 文件,上面的命令不会列出任何其他文件,而只会显示:

ls: *.avi: 没有这样的文件或目录

我注意到在 bash 而不是 zsh 中,它也给出了这个错误,但仍然显示确实存在的文件。

我认为这与通配符匹配/通配符在 zsh 和 bash 环境中工作方式的差异有关。

有没有办法只

ls
所有具有一堆给定扩展名(或其他通配符模式)的文件,无论它们是否全部出现?

zsh wildcard ls
2个回答
2
投票

您需要不止一行代码才能完成此操作。

可以简单地使用 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

2
投票

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
% 
© www.soinside.com 2019 - 2024. All rights reserved.