命令行:管道查找结果到 rm

Posted

技术标签:

【中文标题】命令行:管道查找结果到 rm【英文标题】:Command line: piping find results to rm 【发布时间】:2012-06-26 20:02:10 【问题描述】:

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

find 部分工作,但 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

我做错了什么?

【问题讨论】:

【参考方案1】:

您实际上是通过管道将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.

附注请注意,不能直接通过管道连接到rm,因为rm 不希望标准输入上有文件名。您目前正在做的是将它们向后管道。

【讨论】:

谢谢。我阅读了手册页并尝试了该标志。我正在传递完整路径,但返回“/usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/:相对路径可能不安全”。知道为什么吗? @jerrygarciuh 看看here。 谢谢。我不确定我是否很好地遵循了帖子,但是当我模仿他们的解决方案并将 -delete 放在命令末尾时,它删除了所有 sql 文件,而不管修改时间如何......但它没有警告所以我猜这就是进步…… @jerrygarciuh 哎呀,我希望没有任何有价值的东西丢失......man 说: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. 不过,考虑到你使用的其他选项,我不确定这有什么关系,但你有没有试试看? 不,我没有,但没有丢失任何东西。这些文件是从另一个存储它们的服务器上同步的。【参考方案2】:
find /usr/www/bar/htdocs -mtime +15 -exec rm  \;

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

【讨论】:

我更喜欢你的答案,而不是因为“名称中的空格”而接受的答案。使用“-exec”命令比管道更好地处理它。谢谢。 如何将删除的文件通过管道传输到日志文件? ` rm >> my.log` 不会飞。【参考方案3】:

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

例如,

locate file | xargs rm

【讨论】:

【参考方案4】:

假设您不在包含 *.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  \;

【讨论】:

【参考方案5】:

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

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

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

【讨论】:

以上是关于命令行:管道查找结果到 rm的主要内容,如果未能解决你的问题,请参考以下文章

管道命令

linux head命令(head指令)(获取文件或管道输出结果前n行,默认前10行)与sed命令区别

linux head命令(head指令)(获取文件或管道输出结果前n行,默认前10行)与sed命令区别

linuxWINDOWS命令行下查找和统计行数

PowerShell 学习笔记——管道

Linux常用的命令