以递归方式排除包含特定文件的子文件夹 rm -rf /folder/*

以递归方式排除包含特定文件的子文件夹 rm -rf /folder/*

我想知道是否可以指定一些优雅的条件(可能是参数?)以免rm -rf /folder/*删除其子文件夹,其中包含名为“dontshoot.txt”的文件。

我至今还没能找到任何东西。

在此先感谢您的帮助!

答案1

你可以find像这样简单地使用

find some_folder ! -name dontshoot.txt -delete

这将递归删除除dontshoot.txt文件之外的所有文件和文件夹。正如其他评论中所述,在不删除的情况下进行测试总是有帮助的,只需这样做即可。

find some_folder ! -name dontshoot.txt 

但是这将列出所有文件夹,甚至包含dontshoot.txt但它们的文件夹,因为它们在使用时不会为空,所以不会被删除-delete

编辑:

我同意 fedorqui 对这个问题的解释比我的更合理。只删除那些不包含dontshoot.txt树结构深处某个地方的文件夹,一个非常低效的解决方案是

find some_folder -type d -exec \
   sh -c "find {} -name dontshoot.txt | grep -q '' || echo rm -fr {}" \;

解释:

外部find命令通过递归遍历some_folder查找所有目录(-type d)并执行(-exec)给定的 shell 命令,同时{}用找到的目录的相对路径替换。

findshell 中的命令会在找到的目录中搜索。dontshoot.txt如果未找到任何内容,则不会向其传递任何输出,grep -q '' 因此将返回False,并执行最后一部分,以dontshoot.txt递归方式删除整个目录(该目录肯定不包含 )。

简而言之,它遍历所有目录并删除其中不包含dontshoot.txt某处的目录。

答案2

无法在rm命令中排除它们。

你可以做这样的事情:

for dir in /folder/*
do
  echo $dir
  if [ ! -f "$dir/dontshoot.txt" ]; then
    rm -rf "$dir"
   fi
done

重要的:

执行之前ls用 而不是来检查。rm

答案3

以下功能可以运行,但我没有时间进行测试。

// $1 = directory to remove
// $2 = exclude pattern
function rmx()
{
    rm -f $(find $1 * | grep -v $2)
}

呼叫类似

rmx get/rid/of/this/ ".*?not-these-files.*?"

也许这至少可以作为解决这个问题的一种方法......

相关内容