Linux / Unix:使用一个命令即时查找和删除文件
有时需要找出所有文件并一次性将其删除。但是,rm 命令不支持搜索条件。例如,查找所有“*.bak”文件并删除它们。对于此类需求,您需要使用 find 命令在目录中搜索文件并动态删除它们。您可以将 find 和 rm 命令组合在一起。本页介绍如何使用一个命令动态查找和删除文件。
教程详细信息 | |
---|---|
难度等级 | 简单的 |
Root 权限 | 不 |
要求 | Linux 或 Unix 终端 |
类别 | 文件管理 |
操作系统兼容性 | BSD • Linux • macOS • Unix |
预计阅读时间 | 6 分钟 |
使用一个命令即时查找和删除文件
基本 find 命令语法如下:
find dir-name criteria action
其中,
- dir-name:定义工作目录,例如查看 /tmp/
- criteria:用于选择“*.sh”等文件(所有以.sh扩展名结尾的文件)
- action:查找操作(对文件执行的操作),例如删除文件或打印文件名等。
句法
您想使用一个 find 命令删除多个文件,例如“*.jpg”或“*.sh”。请勿立即运行这些命令。如果不小心,您还可能删除不需要的文件。语法是:
或
以上两个语法之间的唯一区别是第一个命令也删除目录,而第二个命令仅删除文件。其中,选项如下:
$ find . -name "FILE-TO-FIND" -exec rm {} \;
$ find . -name "FILE-TO-FIND" -exec rm [options] {} \;
###################################################
# Like `-name`, but the match is case insensitive.#
###################################################
$ find . -iname "FILE-TO-FIND" -exec rm [options] {} \;
$ find /dir/to/search/ -type f -name "FILE-TO-FIND-Regex" -exec rm {} \;
- -name "FILE-TO-FIND":文件模式。
- -exec rm {} \;:删除所有符合文件模式的文件。如果需要,您可以将该选项传递给 rm 命令。
- -type f:仅匹配文件,不包含目录名。
- -type d:仅匹配目录,不包括文件名。
示例
首先,验证您要删除的文件名。语法如下:
$ find . -name "FILE-TO-FIND" -print
例如,在当前目录中找到您要删除的所有“*.jpg”:
$ find . -name "*.jpg" -print | less
或
$ find . -name "*.jpg" -ls | more
以下是列表:
35403365 64 -rw-rw-r-- 1 vivek vivek 65067 Aug 23 15:54 ./linux-user.jpg 35405315 188 -rw-rw-r-- 1 vivek vivek 190326 Sep 23 04:01 ./c.jpg 35420143 84 -rw-rw-r-- 1 vivek vivek 83278 Aug 23 15:58 ./lxd.gimp.storage/linux-user.jpg 36308902 152 -rw-rw-r-- 1 vivek vivek 154641 May 1 13:41 ./lxd.gimp.storage/local.jpg 36309295 524 -rw-rw-r-- 1 vivek vivek 534156 May 3 17:10 ./lxd.gimp.storage/user.jpg 36308955 152 -rw-rw-r-- 1 vivek vivek 153378 May 5 01:12 ./lxd.gimp.storage/cat.jpg 35394754 60 -rw-rw-r-- 1 vivek vivek 60600 Sep 15 12:59 ./lxd.gimp.storage/tar.jpg 35404175 72 -rw-rw-r-- 1 vivek vivek 72324 Apr 25 00:54 ./lxd.gimp.storage/g.jpg 36309185 232 -rw-rw-r-- 1 vivek vivek 233824 May 3 07:22 ./lxd.gimp.storage/ba.jpg 35430896 60 -rw-rw-r-- 1 vivek vivek 59261 Sep 18 19:19 ./lxd.gimp.storage/t.jpg 36308481 80 -rw-rw-r-- 1 vivek vivek 78177 Apr 25 11:12 ./lxd.gimp.storage/out-freebsd.jpg 35397782 44 -rw-rw-r-- 1 vivek vivek 43087 May 2 14:14 ./lxd.gimp.storage/who.jpg 35409536 32 -rw-rw-r-- 1 vivek vivek 30429 Apr 9 2022 ./Downloads/keep-around/droplet-g104922ce4_64expvaiuyyocqkccxydtlqkiiicsbgujf.jpg 35401394 20 -rw-rw-r-- 1 vivek vivek 17477 Jun 6 02:12 ./Documents/example-twitter-logo.jpg 35392900 188 -rw-r--r-- 1 vivek vivek 188840 Sep 6 2018 ./Documents/equitymaster.jpg
您确定要删除所有列出的文件吗?然后仅运行确认删除:
由于我删除了该选项,以下语法不会提示并删除所有匹配的文件:
$ find . -name "*.jpg" -exec /bin/rm -i {} \;
-i
$ find . -name "*.jpg" -exec /bin/rm {} \;
-delete关于该选项的说明
现代版本的 find 命令-delete也有选项。不使用-exec rm -rf {} \;,而是使用-delete来删除所有匹配的文件。我们还可以明确地将-depth选项传递给 find ,以便在目录本身之前处理每个目录的内容。也可以使用选项-maxdepth来控制在起点以下的大多数目录级别下降。例如,-maxdepth 0意味着只对起点本身应用测试和操作。类似地,我们可以将 将传递-mindepth给 find。这意味着不要在低于 levels(非负整数)的级别应用任何测试或操作。例如,-mindepth 1意味着处理除起点之外的所有文件。所以这里有一个简化的语法:
$ find /dir/to/search/ -type f -name "FILES-TO-FIND" -delete
$ find /dir/to/search/ -type f -name "FILES-TO-FIND" -depth -delete
$ find /dir/to/search/ -maxdepth 2 -type f -name "FILES-TO-FIND" -depth -delete
# find ALL *.bak or *.o or *.core and delete them #
$ find /dir/to/search/ \( -name '*.bak' ‑o -name '∗.o' ‑o -name 'core' \) -delete
find 命令示例
在当前目录中查找所有具有 .bak (*.bak) 扩展名的文件并将其删除:
$ find . -type f -name "*.bak" -exec rm -f {} \;
或者
$ find . -type f -name "*.bak" -delete
在 /(根)目录中查找所有核心文件并将其删除(使用此命令时请小心):
在当前目录中查找所有 *.bak 文件并在用户确认后将其删除:
示例输出:
# find / -name core -exec rm -f {} \;
### OR ###
# find / -name core -delete
$ find . -type f -name "*.bak" -exec rm -i {} \;
rm: remove regular empty file `./data0002.bak'? y rm: remove regular empty file `./d234234234fsdf.bak'? y rm: remove regular empty file `./backup-20-10-2005.bak'? n
总是-delete效果更好,因为它不必为每个匹配的文件生成外部进程(如 rm)。但是,该-delete选项可能并非在所有 find 版本上都可用。因此,我们也可以按如下方式使用 xargs 命令:
$ find . -type f -name "*.err" -print0 | xargs -I {} -0 rm -v "{}"
其中 find 命令选项如下:
- -print0– 强制 find 命令在标准输出上打印完整文件名,后跟一个空字符(而不是 -print 使用的换行符)。这样,处理 find 输出的程序就可以正确解释包含换行符或其他类型空格的文件名。此选项对应于 xargs 的 -0 选项。
xargs 命令选项如下:
- -I {}:将初始参数中的 {} 替换为从标准输入读取的名称。我们将 {} 作为参数传递给 rm 命令。
- -0:输入项以空字符而不是空格结尾,引号和反斜杠不是特殊字符(每个字符都按字面意思理解)。禁用文件结尾字符串,该字符串将像其他任何参数一样处理。当输入项可能包含空格、引号或反斜杠时很有用。GNU find -print0 选项可生成适合此模式的输入。
- rm -v "{}":对匹配的文件运行 rm 命令。
查找和删除文件
在此示例中,查找所有 *.out、*.bak 和 *.core 文件,然后将其删除:
$ find /projectA/ \( -name '∗.bak' -o -name '*.core' \) -exec rm "{}" \;
我们将文件类型(例如 *.bak 和 *.core)放在括号之间。每个文件类型后面都跟有 -name。例如-name '*.c'。然后我们使用运算符语法构建列表:
( expr1 -o expr2 )
\( -name '*.out' -o -name '∗.bak' ‑o -name '*.core' \)
结论
使用 man 命令或 help 命令阅读以下手册页:
有关 find 命令的详细信息,请参阅使用 find 命令查找/定位文件第 1 部分、第 2 部分。
$ man find
$ man xargs
$ man rm