162

我正在尝试制定一个删除超过 15 天的 sql 文件的命令。

查找部分正在工作,但不是 rm。

rm -f | find -L /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups -type f  \( -name '*.sql' \) -mtime +15

它会准确列出我要删除的文件,但不会删除它们。路径是正确的。

usage: rm [-f | -i] [-dIPRrvW] file ...
       unlink file
/usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/20120601.backup.sql
...
/usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/20120610.backup.sql

我究竟做错了什么?

4

5 回答 5

314

您实际上是通过管道将rm输出连接到 的输入find。你想要的是使用find作为参数的输出rm

find -type f -name '*.sql' -mtime +15 | xargs rm

xargs是将其标准输入“转换”为另一个程序的参数的命令,或者,更准确地说,他们将其放在man页面上,

从标准输入构建和执行命令行

请注意,如果文件名可以包含空格字符,则应更正:

find -type f -name '*.sql' -mtime +15 -print0 | xargs -0 rm

但实际上,find有一个捷径:-delete选项:

find -type f -name '*.sql' -mtime +15 -delete

请注意以下警告man find

  Warnings:  Don't  forget that the find command line is evaluated
  as an expression, so putting -delete first will make find try to
  delete everything below the starting points you specified.  When
  testing a find command line that you later intend  to  use  with
  -delete,  you should explicitly specify -depth in order to avoid
  later surprises.  Because -delete  implies  -depth,  you  cannot
  usefully use -prune and -delete together.

PS请注意,直接管道rm不是一个选项,因为rm不期望标准输入上的文件名。您目前正在做的是将它们向后输送。

于 2012-06-25T15:03:04.907 回答
33
find /usr/www/bar/htdocs -mtime +15 -exec rm {} \;

将选择/usr/www/bar/htdocs超过 15 天的文件并将其删除。

于 2013-08-30T10:57:28.600 回答
6

另一种更简单的方法是使用locate命令。然后,将结果通过管道传输到xargs.

例如,

locate file | xargs rm
于 2017-04-27T13:23:36.387 回答
3

假设您不在包含 *.sql 备份文件的目录中:

find /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/*.sql -mtime +15 -exec rm -v {} \;

上面的 -v 选项很方便,它会在删除文件时详细输出正在删除的文件。

我喜欢列出将首先删除的文件以确保。例如:

find /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/*.sql -mtime +15 -exec ls -lrth {} \;
于 2017-06-06T03:07:49.287 回答
1

使用xargs传递参数,使用选项-rd '\n'忽略名称中的空格:

"${命令}" | xargs -rd '\n' rm

如果您还想删除只读文件,请包括--force 。

于 2021-05-17T23:09:12.440 回答