命令行:管道查找结果到 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命令区别