Linux 使用;查找…-删除“;仅从特殊子目录删除图像文件的步骤

Linux 使用;查找…-删除“;仅从特殊子目录删除图像文件的步骤,linux,bash,shell,ubuntu-14.04,linux-mint,Linux,Bash,Shell,Ubuntu 14.04,Linux Mint,我需要清理我的音乐收藏中一些不需要的图像的子目录。我正在使用Ubuntu14.04和/或LinuxMint17.2,以及使用find命令的bashshell脚本 目录结构(最小示例)如下所示: Tagged Artist #1 Artist #1 - An Album Artist #1 - A Track.flac cover.jpg something.png Artist #1 - [compilations] Artis

我需要清理我的音乐收藏中一些不需要的图像的子目录。我正在使用Ubuntu14.04和/或LinuxMint17.2,以及使用find命令的bashshell脚本

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

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和/或png图像(因为标记软件错误地将它们放在那里)。任何碰巧在普通“相册”文件夹中的图像我也希望保留

在我的目录结构中,名称中带有“[编译]”的文件夹只能分别出现在“艺术家”文件夹的正下方;因此,最大深度为两层

我想出了以下find命令:

$ cd Tagged
$ find . -maxdepth 2 -type d -name '*\[compilations\]' -exec find {} -type f -iname '*.jp*g' -or -iname '*.png' -delete \;
这似乎有些作用,需要一些时间,但文件“/Artist#1/Artist#1-[compilements]/cover.jpg”和“/Artist#1/Artist#1-[compilements]/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
下面是我的问题:

  • 为什么-delete不起作用
  • 对于路径和文件名中的空格、全局字符和外来字符等“奢侈”,此命令真的安全吗
  • 我如何重写上面的命令,仍然使用bash和find
  • 命令是否可以优化(重新加速、安全、嵌套查找)
在实际集合中,该命令必须遍历16899个文件夹,几乎所有文件夹都包含空格和外来字符(如捷克语、俄语、日语、希腊语、德语……),因此它必须是健壮的


提前感谢您的见解和一些启示

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

因此,我认为正确的命令应该是:

$ find . -depth -maxdepth 2 -type d -name '*\[compilations\]' -exec find {} -type f \( -iname '*.jp*g' -or -iname '*.png' \) -delete \;
在上面的测试用例中,它似乎工作正常


尽管如此,还是需要一些确认。A可能是我其他问题的一些答案,仅供参考和学习。谢谢大家!

您的
-delete
谓词仅适用于

-iname '*.png'
谓词,因为您遗漏了分组:当您给出
查找
以下内容时:

-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
检查命令。)

find
命令中有一个
find
命令很奇怪。。。无论如何,您的删除只适用于
-iname'*.png'
谓词,因为您遗漏了一些分组。要检查将要发生的情况,请将
-delete
谓词替换为
-print
谓词。您将看到
find
忽略了所有jpg。使用分组:
\(-iname'*.jp*g'-或-iname'*.png'\)
@gniourf\u gniourf我真的想不出用一个
find
命令来实现这一点的方法。我认为
find
-from-
find
是正确的选择。不过,你对分组的看法是正确的;你应该把它贴出来作为回答。谢谢你!经过更多的实验后,我也想到了同样的想法。是的,请将此作为回答,我很乐意接受你的回答,而不是我的;-)感谢您解释@gniourf\u gniourf!听起来只使用一个发现是个不错的主意,但现实生活更复杂。当从其他地方调用时,您提供的路径是否仍然有效,例如:
find/home/$USER/Musik/taged/-maxdepth 3-path'*/*\[compilements\]/*'\\(-iname'*.jp*g'-o-iname'*.png'\)-type f-print
?抱歉问了一个愚蠢的问题,我以前从未使用过-path…仍然需要学习这么多东西!:-)@月球基地是的,它会工作的!(试试看,
-print
而不是
-delete
使命令无害)。但请引用您的变量扩展:
“/home/$USER/Musik/taged”
(带双引号)。再次干杯,刚刚尝试过,效果非常好。我猜不筑巢也会快得多,会在以后的真实收集中计时。感谢您对$USER部分进行四舍五入的提示…我没有“奇怪”的用户名,但您是对的,请始终注意安全!:-)对于那些感兴趣的人:在总共16899个文件夹的音乐集合中,“嵌套查找”花费了3.285秒,而gniourf_gniourf的解决方案(只有一个查找)只花费了0.324秒!(使用时间的实时测量)哇。非常感谢。