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

我需要从不需要的图像中清理音乐collections中的一些子目录。 我正在使用find命令使用Ubuntu 14.04和/或Linux Mint 17.2以及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]”结尾的子文件夹中,我想删除所有types的jpeg和/或png图像(因为标记软件错误地将它们放在那里)。 任何发生在正常的“相册”文件夹中的图像,我也希望保持。

通过我的目录结构,名称中只有“[compilations]”的文件夹只能在“Artist”文件夹下方发生, 所以最多两层深。

我想出了以下查找命令:

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

这似乎做了一些事情,需要一段时间,但文件“./艺术家#1 /艺术家#1 – [编辑] / cover.jpg”“./艺术家#1 /艺术家#1 – [汇编] /东西。 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 

所以这是我的问题:

  • 为什么-delete不工作?
  • 这个命令是否真的安全,像“空余”,如空白,glob字符和外部字符的path和文件名?
  • 我将如何重写上述命令,仍然使用bashfind
  • 命令是否可以优化(重新加速,安全,嵌套查找)?

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

提前感谢任何见解和启发!

你的-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 

我建议,为了实验你用-print替换-delete :你将看到-delete适用于什么!

现在,关于你的嵌套find :因为你的目录树的结构(你的文件只有深度3),所以你应该只能使用find一个实例:

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

(我把-print代替-delete这样你可以在执行之前用-delete来检查这个命令)。

经过一番实验,我认为我的错误并不是把OR的部分放在括号里,似乎只在最后一个OR右边部分使用了-delete ,即试图删除'* .png'。 唉,几乎所有的封面图片都是'* .jpg',所以我认为它根本不起作用!

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

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

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

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