创建一个bash脚本以删除不包含特定文件类型的文件夹

时间:2014-02-18 02:58:29

标签: linux bash shell

我最近遇到了一个问题。

我使用了一个实用程序将所有音乐文件移动到基​​于标签的目录中。这留下了很多几乎个空文件夹。通常,文件夹包含thumbs.db文件或用于专辑封面的某种图像。这些mp3在他们的新目录中有正确的专辑封面,所以旧的可以删除。

基本上,我需要在D:/ Music /中找到任何目录:

- 没有任何子目录

- 不包含任何mp3文件

然后删除它们。

我认为这在shell脚本或bash脚本或其他任何linux / unix世界中比在Windows 8.1(HAHA)中更容易。

有什么建议吗?我写这样的剧本并不是很有经验。

2 个答案:

答案 0 :(得分:3)

这应该让你入门

find /music -mindepth 1 -type d |
while read dt
do
  find "$dt" -mindepth 1    -type d | read && continue
  find "$dt" -iname '*.mp3' -type f | read && continue
  echo DELETE $dt
done

答案 1 :(得分:0)

这是短篇小说......

find . -name '*.mp3' -o -type d -printf '%h\n' | sort | uniq > non-empty-dirs.tmp
find . -type d -print | sort | uniq > all-dirs.tmp
comm -23 all-dirs.tmp non-empty-dirs.tmp > dirs-to-be-deleted.tmp

less dirs-to-be-deleted.tmp

cat dirs-to-be-deleted.tmp | xargs rm -rf

请注意,在完成删除所有递归空目录之前,可能需要多次运行所有命令(具体取决于存储库的目录深度)...

长话故事......

您可以从两个基本角度处理此问题:要么找到所有目录,要么遍历每个目录,检查它是否包含任何mp3文件或任何子目录,如果没有,请将该目录标记为删除。它可以工作,但是在大型非常大的存储库中,您可能会预计会有大量的运行时间。

另一种方法,在我看来更有趣,是建立一个不被删除的目录列表,并从所有目录列表中减去该列表。让我们一步一步地实施第二个战略......

首先,要查找包含mp3文件的所有目录的路径,您只需执行以下操作:

find . -name '*.mp3' -printf '%h\n' | sort | uniq

这意味着“查找任何以.mp3结尾的文件,然后打印到其父目录的路径”。

现在,我当然可以命名至少十种不同的方法来查找包含至少一个子目录的目录,但是保持与上面相同的策略,我们可以很容易地得到......

find . -type d -printf '%h\n' | sort | uniq

这意味着:“找到任何目录,然后打印它的父路径。”

这两个查询都可以在一次调用中组合,生成一个包含所有目录不可删除的路径的列表。让我们将该列表重定向到一个临时文件。

find . -name '*.mp3' -o -type d -printf '%h\n' | sort | uniq > non-empty-dirs.tmp

让我们类似地生成一个包含所有目录路径的文件,无论它们是否为空。

find . -type d -print | sort | uniq > all-dirs.tmp

所以,我们一方面有所有目录的完整列表,另一方面,我们有不要删除的目录列表。现在怎么办?有很多策略,但这里有一个非常简单的策略:

comm -23 all-dirs.tmp non-empty-dirs.tmp > dirs-to-be-deleted.tmp

一旦你拥有了这个,那么审查它,如果你满意,那么将它通过xargs传递给rm以实际删除这些目录。

cat dirs-to-be-deleted.tmp | xargs rm -rf