我正在尝试在终端中按顺序列出丢失的文件。虽然这里存在许多答案,但它们不够通用,我无法根据我的情况进行调整。因此,如果您可以做出一个足够通用且适合更多人的答案,请这样做。
我正在ls {369..422}.avi >/dev/null
列出丢失的文件,但无法使用 * 来匹配以 .avi 结尾的任何文件。我怎样才能做到这一点?
数字不在文件末尾,而是在中间。所以我应该需要类似的东西*numbers*.avi
答案1
ls *{369..422}*.avi >/dev/null
这将首先生成类似的模式
*369*.avi
*370*.avi
*371*.avi
*372*.avi
*373*.avi
*374*.avi
通过大括号扩展,然后ls
将使用这些模式执行,这将为每个无法扩展为当前目录中的名称的模式提供错误消息。
或者,如果您没有*
名称中包含以下内容的文件:
for name in *{369..422}*.avi; do
case "$name" in
'*'*) printf '"%s" not matched\n' "$name" ;;
esac
done
这依赖于这样一个事实:如果模式与当前目录中的名称不匹配,则该模式将保持未展开状态。这为您提供了一种可能对丢失文件执行有用操作的方法,而无需解析ls
.
答案2
如果你愿意*numbers*.avi
,你可以这样做:
ls *[0-9]*.avi
指定一个字符类,由您的语言环境之间和语言环境中[0-9]
的所有字符组成。这应该是所有数字。因此,您想要匹配 0 个或多个字符 ( ),然后匹配一个数字,然后再次匹配 0 个或多个字符 ( )。0
9
*
[0-9]
*
如果您需要按顺序排列多个数字,请使用:
ls *[0-9][0-9]*.avi
最后,如果您有按数字顺序排列的文件并且只想找到丢失的文件,您还可以编写一个小循环:
for avi in {369..422}.avi; do [ -e "$avi" ] || echo "$avi missing"; done
答案3
要列出哪些模式*{369..422}*.avi
与任何文件都不匹配,zsh
您可以执行以下操作:
for p (\*{369..422}\*.avi) () {(($#)) || echo $p} $~p(N[1])
或者更详细地说:
for p (\*{369..422}\*.avi) () {
if (($#)); then
echo "$# file(s) matching $p"
else
echo >&2 No file matching $p
fi
} $~p(N)
对于遵循固定模式(例如:)的文件foo-123-bar.avi
,您还可以执行以下操作:
expected=(foo-{369..422}-bar.avi)
actual=($^expected(N))
missing=(${expected:|actual})
print -l $missing
其中的一些zsh
特定功能:
x{1..20}y
大括号扩展扩展为x1y
,x2y
.... 此后被其他一些 shell 复制。for var (values) cmd
for
:循环的简短形式() compound-command args
:匿名函数就像许多其他语言一样。$~p
:将 的内容视为$p
一个全局变量(其他 shell 默认情况下会这样做,甚至会进行分词!)(N[1])
:glob 限定符,当它们不匹配任何文件时,glob 扩展为无参数。[1]
只选择第一个匹配的文件,因为我们只有一个来判断是否有匹配。$^array
:数组中元素的大括号式扩展${array1:|array2}
:数组减法print -l
:按行打印
答案4
您可以尝试:
ls *{369..422}*.avi