使用 "find … -delete" 仅从特殊子目录中删除图像文件

Using "find … -delete" to remove image files only from special subdirectories

我需要清理音乐 collection 中一些子目录中不需要的图像。我正在使用 Ubuntu 14.04 and/or Linux Mint 17.2 和使用 find 命令的 bash shell 脚本。

目录结构(最小示例)如下:

Tagged
  Artist #1
    Artist #1 - An Album
      Artist #1 - A Track.flac
      cover.jpg
      something.png
    Artist #1 - [compilations]
      Artist #1 - A Track.flac
      cover.jpg
      something.png
  Artist #2
    Artist #2 - Another Album
      Artist #2 - A Track.mp3
      cover.jpg

只有在以“[compilations]”结尾的子文件夹中,我想删除所有jpeg and/or png图像(因为标记软件错误地把它们那里)。任何恰好位于普通 "album" 文件夹中的图像我也希望保留。

根据我的目录结构,名称中带有“[compilations]”的文件夹只能出现在 "Artist" 文件夹的正下方;所以最多两层深。

我想到了以下查找命令:

$ cd Tagged
$ find . -maxdepth 2 -type d -name '*\[compilations\]' -exec find {} -type f -iname '*.jp*g' -or -iname '*.png' -delete \;

这似乎需要一些时间,但文件 "./Artist #1/Artist #1 - [compilations]/cover.jpg""./Artist #1/Artist #1 - [compilations]/something.png" 仍然存在(以及所有其他图像文件)。

作为 Linux 的新手,我假设我在使用 find-delete 选项时犯了一个愚蠢的错误,因为以下命令(没有 -delete)正确显示文件:

$ find . -maxdepth 2 -type d -name '*\[compilations\]' -exec find {} -type f -iname '*.jp*g' -or -iname '*.png' \;
./Artist #1/Artist #1 - [compilations]/cover.jpg
./Artist #1/Artist #1 - [compilations]/something.png

所以这是我的问题:

在实际collection中,该命令必须遍历16899个文件夹,几乎所有文件夹都包含空格和外来字符(如捷克语、俄语、日语、希腊语、德语……),因此它必须是健壮的。

在此先感谢您的任何见解和启发!

经过一些实验,我认为我的错误是没有将 OR 部分 放在括号 中——似乎 find 使用了-delete 仅在最后一个 OR 的 右侧,即试图删除“*.png”。唉,我几乎所有的封面图片都是“*.jpg”,所以我认为它根本行不通!

所以我认为更正的命令应该是:

$ find . -depth -maxdepth 2 -type d -name '*\[compilations\]' -exec find {} -type f \( -iname '*.jp*g' -or -iname '*.png' \) -delete \;

它似乎在我上面的测试用例上工作正常。

尽管如此,一些确认会很好。也许是我其他问题的一些答案,仅供参考和学习。 谢谢!

您的 -delete 谓词仅适用于

-iname '*.png'

谓词,因为您错过了分组:当您给出 find 以下内容时:

-type f -iname '*.jp*g' -or -iname '*.png' -delete

由于布尔运算符的优先级,find理解为:

\( -type f -iname '*.jp*g' \) -or \( -iname '*.png' -delete \)

要解决此问题,请使用:

-type f \( -iname '*.jp*g' -or -iname '*.png' \) -delete

我建议您将 -delete 替换为 -print 进行实验:您会看到 -delete 适用于什么!

现在,关于您的嵌套 find:由于目录树的结构(您的文件仅在深度 3 中),您应该只能处理 find 的一个实例:

find -maxdepth 3 -path '*/*\[compilations\]/*' \( -iname '*.jp*g' -o -iname '*.png' \) -type f -print

(我用 -print 而不是 -delete 以便您可以在使用 -delete 执行命令之前检查命令)。