如何 "rm -rf" 使用 "find -o" 命令排除文件和文件夹

How to "rm -rf" with excluding files and folders with the "find -o" command

我正在尝试使用 find 命令,但仍然不知道如何将 find ... 传送到 rm -rf

这里是用于测试的目录树:

/path/to/directory
/path/to/directory/file1_or_dir1_to_exclude
/path/to/directory/file2_or_dir2_to_exclude
/path/to/directory/.hidden_file1_or_dir1_to_exclude
/path/to/directory/.hidden_file2_or_dir2_to_exclude

/path/to/directory/many_other_files
/path/to/directory/many_other_directories

删除整个目录的命令如下:

rm -rf /path/to/directory

但是如何rm -rf同时排除文件和文件夹?

这里是man帮助参考:

man find

-prune True;  if  the  file is a directory, do not descend into it.  If
      -depth is given, then -prune has no effect.  Because -delete im‐
      plies  -depth,  you  cannot  usefully use -prune and -delete to‐
      gether.
        For example, to skip the directory `src/emacs' and  all  files
      and directories under it, and print the names of the other files
      found, do something like this:
                find . -path ./src/emacs -prune -o -print

这个 find 命令中的 -o 是什么?是“或”的意思吗?我在手册页中找不到 -o 的含义。

mkdir -p /path/to/directory

mkdir -p /path/to/directory/file1_or_dir1_to_exclude
mkdir -p /path/to/directory/file2_or_dir2_to_exclude

mkdir -p /path/to/directory/.hidden_file1_or_dir1_to_exclude
mkdir -p /path/to/directory/.hidden_file2_or_dir2_to_exclude

mkdir -p /path/to/directory/many_other_files
mkdir -p /path/to/directory/many_other_directories

我曾尝试使用此 find 命令排除 .hidden_file1_or_dir1_to_exclude,然后将其通过管道传输到 rm,但此命令无法按预期工作。

cd /path/to/directory
find . -path ./.hidden_file1_or_dir1_to_exclude -prune -o -print | xargs -0 -I {} rm -rf {}

您需要将文件与目录分开以排除:

find . -mindepth 1\
       \( -path ./dir_to_exclude -o\
          -path ./.hidden_dir_to_exclude \) -type d -prune\
       -o\
     ! \( -path ./file_to_exclude -o\
          -path ./.hidden_file_to_exclude \)\
        -exec echo rm -rf {} \;

您可以在测试后删除 echo

rm -rf的意思是递归删除目录树中的所有内容。

避免递归删除目录中所有内容的方法是让 find 准确枚举您要删除的文件,而不是其他任何内容(当然您不需要 rmfind 也知道如何删除文件)。

find . -depth -path './.hidden_file1_or_dir1_to_exclude/*' -o -delete

使用-delete 开启-depth选项,禁用-prune;但只是说“如果不在这棵树中则删除”。事实上,正如您似乎已经发现的那样,-o 代表“或”。

-delete 启用 -depth 的原因应该很明显;删除目录后无法遍历目录内的文件

顺便说一句,如果使用xargs -0,则需要使用-print0。 (此工具是 GNU 扩展,通常在 POSIX 上不可用。)