在bash脚本中删除所有文件但保留所有目录?

22

我希望做一些可能非常简单的事情,我有一个目录结构,例如:

dir/
    subdir1/
    subdir2/
        file1
        file2
        subsubdir1/
            file3
我想在Bash脚本中运行一个命令,可以递归地删除从目录往下的所有文件,但是保留所有目录。例如:
dir/
    subdir1/
    subdir2/
        subsubdir1

这个需要什么样的命令?

4个回答

42
find dir -type f -print0 | xargs -0 rm

find 命令会在给定目录中递归查找所有符合特定表达式的文件。 -type f 匹配常规文件。 -print0 用于使用 \0 作为分隔符输出名称(因为路径中可能包含任何其他字符,包括\n)。 xargs 用于从标准输入中收集文件名并将它们作为参数传递。 -0 是为了确保 xargs 能够理解 \0 分隔符。

xargs 足够智能,如果参数列表过长,会多次调用 rm 。因此,它比尝试调用类似 rm $((find ...) 的方法要好得多。另外,它比每个文件单独调用 rm (例如 find ... -exec rm \{\})更快。


10

使用 GNU 的 find 命令,可以使用 -delete 动作:

find dir -type f -delete

使用标准的find命令,您可以使用-exec rm来删除文件:

find dir -type f -exec rm {} +

8
find dir -type f -exec rm {} \;

其中dir是您想要删除文件的顶层目录。

请注意,这将仅删除常规文件,而不是符号链接、设备等。如果您想删除除目录以外的所有内容,请使用:

find dir -not -type d -exec rm {} \;

这真的取决于所使用的 shell。"花括号扩展" 可以在新的 bash 或 zsh 中发生。这就是为什么我总是对它们进行转义的原因。 - liori

8
find dir -type f -exec rm '{}' +

3
“-exec” 命令有两种终止方式:分号或加号。如果使用分号,则为每个单独的文件生成一个新进程。如果使用加号,则只生成一个进程。(实际上,如果命令行过长,则会生成多个进程 - 基本上它的工作方式类似于“xargs”,但没有引用问题。)例如,您有两个名为 A 和 B 的文件。然后,使用分号将生成两个进程:“rm A”和“rm B”。而使用加号,则只生成一个进程:“rm A B”。 - Jörg W Mittag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接