我正在尝试删除所有子目录(以及其中的文件)不是在 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 {} +
所有这些命令都会删除内容。使用前进行测试!