【问题标题】:find command: delete everything but one folder查找命令:删除除一个文件夹外的所有内容
【发布时间】:2020-09-06 14:43:49
【问题描述】:

我有这个命令:

find ~/Desktop/testrm -mindepth 1 -path ~/Desktop/testrm/.snapshot -o -mtime +2 -prune -exec rm -rf {} +

我希望它按原样工作,但它必须避免删除特定目录 ($ROOT_DIR/$DATA_DIR)。

  • 它必须删除目录中的文件,而不是目录本身
  • rm 中的标志“r”是必需的,因为它必须删除其他目录
  • -prune 不适合,因为它会丢弃内容和子目录

【问题讨论】:

标签: linux bash find rm


【解决方案1】:

您可以使用-o 的短路行为排除单个路径(就像您已经对~/Desktop/testrm/.snapshot 所做的那样)。 但是,对于每个排除的路径,您还必须排除其所有父目录。否则,您将通过删除 a/b/a/rm -rf 来删除 a/b/c

在以下脚本中,函数orParents 生成find 命令的一部分。示例:
find $(orParents a/b/c) ... 将运行
find -path a/b/c -o -path a/b -o -path a -o ...

#! /usr/bin/env bash
orParents() {
  p="$1"
  while
    printf -- '-path %q -o' "$p"
    p=$(dirname "$p")
    [ "$p" != . ]
  do :; done
}
find ~/Desktop/testrm -mindepth 1 \
  $(orParents "$ROOT_DIR/$DATA_DIR") -path ~/Desktop/testrm/.snapshot -o \
  -mtime +2 -prune -exec rm -rf {} +

警告:您必须确保$ROOT_DIR/$DATA_DIR / 结尾并且 包含全局字符,例如*?[]
空格可以,因为printf %q 可以正确转义它们。但是,find -path 将其参数独立地解释为 glob 模式。我们可以做一个双引号机制。也许像printf %q "$(sed 's/[][*?\]/\\&/' <<< "$p")" 这样的东西,但我不太确定find -path 究竟是如何解释它的论点的。

或者,您可以编写一个脚本isParentOf 并执行...

find ... -exec isParentOf "$ROOT_DIR/$DATA_DIR" {} \; -o ... 

... 排除 $ROOT_DIR/$DATA_DIR 及其所有父母。如果您不想将脚本文件添加到路径中,这可能更安全、更便携,但设置起来更慢且麻烦(find -exec bash -c ... 等)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    相关资源
    最近更新 更多