使用find查找某个目录并删除其中除一个目录外的所有文件

Zet*_*ttt 5 find

我有以下问题。我有一个目录结构,想删除名为Caches. 除了所有名为Snapshots. 我不知道如何使用find或我知道的任何其他命令来做到这一点。

我问的原因:在 iOS 上,每个应用程序都有自己的 Caches 目录。这些有时无法正确清除,具体取决于应用程序。有了这个答案的解决方案,当设备的驱动器安装在另一台计算机上时,例如使用 FUSE (iExplorer),人们将能够清除 iOS 上的缓存,从而优化磁盘空间。

这是我到目前为止:

find . 2>/dev/null -type d -name "Caches" -maxdepth 3 -print
Run Code Online (Sandbox Code Playgroud)

这将返回如下内容:

./Library/Caches
Run Code Online (Sandbox Code Playgroud)

当我执行 a 时,ls ./Library/Caches我会看到Snapshots我想排除的所有内容和目录,因为最终我想要-delete除此之外的所有内容。


我想要这样的东西:

  Before:                            After:

  .                                  .
  ??? a                              ??? a
  ?   ??? a                          ?   ??? a
  ?   ??? Caches                     ?   ??? Caches
  ?       ??? a                      ?       ??? a
  ?       ?   ??? Snapshots          ?           ??? Snapshots
  ?       ?       ??? a              ?               ??? a
  ?       ??? b                      ??? b
  ?       ?   ??? a                      ??? c
  ?       ??? c                  
  ??? b
      ??? c
      ??? Caches
          ??? a
          ?   ??? foo
          ?       ??? a
          ??? b
              ??? a
Run Code Online (Sandbox Code Playgroud)

Gra*_*eme 7

我对问题的措辞有些困惑。如果您想要做的是删除./Library/Caches目录中除了名为 的单个文件夹之外的所有内容Snapshots,则无需使用find. 在 中bash,shell globs 是最简单的方法:

shopt -s extglob  # probably already enabled
echo Library/Caches/!(Snapshots)
Run Code Online (Sandbox Code Playgroud)

如果这会打印您要删除的所有文件/目录,请替换echorm -f --.

如果Snapshots在下面的目录树的不同级别有多个目录./Library/Caches要保留,则使用 GNUfind可以执行以下操作:

find Library/Caches ! -path '*Snapshots*'
Run Code Online (Sandbox Code Playgroud)

这应该打印所有文件/目录,不包括Snapshots 路径中的文件/目录。它将包含包含(或其子包含)Snapshots目录的目录,但find ... -delete不会删除这些目录,而是打印它们不为空的错误。一旦你高兴,添加-delete到最后。

一个警告是,这将使所有命名的文件Snapshots完好无损。如果这是一个问题,请执行以下操作:

find Library/Caches \( ! -path '*Snapshots*' -o -type f -name Snapshots \)
Run Code Online (Sandbox Code Playgroud)

-delete高兴的时候再补充。


Sté*_*las 6

find . -depth -print0 | perl -0lne '
  if ("$_/" =~ m{/Caches(/.*)}s && $1 !~ m{/Snapshots/}) {rmdir $_ or unlink $_}'
Run Code Online (Sandbox Code Playgroud)

如果您find不支持-print0,您可以将其替换为-exec printf '%s\0' {} +

这个想法是打印以 NUL 结尾的文件列表(因为 0 是唯一不能出现在文件路径中的字节)并使用perl's -nwith-0选项为每个文件名运行一些代码($_设置为文件名)。

使用-depth,文件在其父目录之前打印。如果文件或目录depth的路径/Caches/不包含/Snapshosts/.