在 OSX 上递归删除不包含模式的子目录

在 OSX 上递归删除不包含模式的子目录

我正在尝试删除所有子目录(以及其中的文件)不是在 OSX 上使用 Bash 在目录名称中包含两种模式之一。我正在尝试递归地执行此操作 - 对于一堆父目录。

让我们说一下我想要的子目录中的模式不是删除是“foobar”或“doobar”

我有一大堆父目录,比如这个:

Parent001_dir
   001_boo
   002_hugs
   003_foobar
   004_doobar
   005_apple
   ...

我想运行一个 for 循环代码,该代码将进入每个父目录并删除不匹配的子目录。

我认为可以工作的代码:

for i in /path/to/parent/directories/
do
find !-name "*foobar*" -o !-name "*doobar*"  -delete
done

但我阅读了查找手册,没有看到任何选项不是匹配模式; !-name 不是一个选项。

编辑-来自评论,尝试:

find /path/to/parent/directories/ -type d -not -name "*foobar*" -not -name "*doobar*"  -delete

并收到“路径可能不安全”消息

如果我找到一种方法来修复我的代码,我最终可以得到“Parent001_dir”和所有其他父目录,如下所示:'

Parent001_dir
   003_foobar
   004_doobar

是否有通配符可以修复我的代码?或者我应该完全使用另一种方法?预先感谢您的任何帮助。

答案1

首先,不需要循环,find它本身就可以完成所有这些工作。您可以使用!-not标志来否定条件。您也不希望,-o因为这意味着“查找名称不是 foobar 或名称不是 doobar 的文件/目录”。这将找到所有内容,因为一个或另一个条件始终为真(foobar匹配“not doobar”并doobar匹配“not foobar”)。你想要的是这样的:

find /path/to/parent/dirs/* -type d ! -name "*foobar*" ! -name "*doobar*" -delete

或者

find /path/to/parent/dirs/* -type -d -not -name "*foobar*" -not -name "*doobar*" -delete

如果您愿意,您也可以在 shell 中执行此操作。例如,使用bash

for i in /path/to/parent/dirs/*/; do 
    [[ "$i" =~ 'foobar' || "$i" =~ 'doobar' ]] || rm -rf "$i"; 
done

我不确定细节,而且我没有 Mac 来测试这个,但看起来 OSX find 不会让你删除目录。我相信(但不确定)那就是这样这段代码做:

/* Potentially unsafe - do not accept relative paths whatsoever */
if (strchr(entry->fts_accpath, '/') != NULL)
    errx(1, "-delete: %s: relative path potentially not safe",
        entry->fts_accpath);

解决这个问题的一种方法是使用-exec

find /path/to/parent/dirs/ -type d ! -name "*foobar*" ! -name "*doobar*"  \
    -exec rm -rf {} +

所有这些命令都会删除内容。使用前进行测试!

相关内容