如何根据文件的 MIME 类型删除文件?

如何根据文件的 MIME 类型删除文件?

(大家好!特别向大家问好,因为这是我在这里发表的第一篇文章。)

我想使用命令根据文件夹及其子文件夹中的 MIME 类型删除文件,例如 .webp 和 .png 图片。我的计算知识几乎为0,但我已经设法根据它们的扩展名删除它们。

首先进入想要的文件夹:

cd /my-folder

然后:

find \( -iname "*.webp" -o -iname "*.png" \) -print0 | xargs -0 rm -f

有人已经在另一个论坛上给了我答案,该命令可以工作,但速度非常慢,比如 70 个文件需要 10 秒,因此我无法使用它。

while read -d '' Fichier
do
  MimeType=$(mimetype --output-format %m "$Fichier") 
  [[ "${MimeType}" == @(image/webp|image/png) ]] && echo rm "$Fichier"
done < <(find . -type f -print0)

这似乎是一个如此“简单”的任务......

答案1

exiftool可用于报告被识别为给定 MIME 类型的文件:

exiftool -q -r. -ext '*' -if '
  print "$FilePath\0" if $MIMEType =~ m{^image/(webp|jpeg)$}; 0' . |
  xargs -r0 echo rm

echo如果看起来正确,请删除)

  • -q: 安静的
  • -r.:递归搜索(注意它遵循目录的符号链接!),包括隐藏目录
  • -ext '*':不限制具有已知扩展名的文件
  • -if 'perl code':仅报告有关代码返回 true 的文件的信息。在这里,我们添加一个;0返回 false,这样就不会选择任何文件,因为我们想要打印以 NUL 分隔的文件路径,我们通过print在代码中调用来实现这一点。这样做-if '$MIMEType eq "image/webp"' -s3 -FilePath会打印以换行符分隔的路径,这不能可靠地进行后处理,因为换行符与文件路径中的任何字符一样有效。

或者您可以exiftool删除文件本身:

exiftool -q -r. -ext '*' -if '
  if ($MIMEType =~ m{^image/(webp|jpeg)$}) {
    print STDERR "Deleting $FilePath\n";
    unlink $FilePath or print STDERR "Failed: $!\n";
  }
  0' .

答案2

你可以合并测试

find -type f \( -iname "*.webp" -o -iname "*.png" \) \
-exec bash -c 'grep image <<<"$(mimetype -b "$1")"' bash {} \; \
-delete

它能做什么:

  1. 行:仅搜索文件 ( ) 并按以或type f结尾的名称进行筛选.webp.png

  2. 行:运行 bash 脚本,其中

    2.1.mimetype b "$1"返回参数号的 mimetype。 1 仅在脚本中。-b跳过返回文件名,因此以下字符串搜索不会同时包含名称包含“image”的文件

    2.2.使用grep;在返回的 mimetype 中搜索字符串“image”如果找到字符串则grep成功(退出状态)0

    2.3.这一切都必须包含在 bash 脚本中,因为命令替换不能很好地与find;一起使用。请注意bash 的参数编号开始于0`bash -c 'script' arg0 arg1 arg2 ...', hence the extra

  3. line 删除先前命令成功的所有匹配项。也许可以替换-delete-print进行试运行,显示哪些文件受到影响。

find | xargs rm还有关于您问题中的 - 组合的提示:

find有自己的删除工具:

find -name '*png' ....<other refinements> ... -delete

但要小心,只能放在-delete最后。很久以前,我就通过艰难的方式了解到这一点......

答案3

file可能比您的mimetype¹ 或exiftool写入的内容更有效perl,特别是如果您为许多文件调用一次,您可以这样做:

find . -type f -exec file -00 --mime-type {} + |
  perl -0lne '$file = $_; chomp($type = <>);
              print $file if $type =~ m{^image/(webp|jpeg)\z}' |
  xargs -r0 echo rm

print $file您可以执行unlink $file并跳过该| xargs rm部分,而不是:

find . -type f -exec file -00 --mime-type {} + |
  perl -0lne '$file = $_; chomp($type = <>);
              if ($type =~ m{^image/(webp|jpeg)\z}) {
                warn "Deleting $file\n";
                unlink $file or warn "Failed: $!\n"
              }'

在我的测试中,mimetype似乎也难以处理非 UTF-8 编码文本的文件路径,因此可能无法处理任意文件路径。

相关内容