Shell脚本编程:使用bash和xargs

11

我正在尝试编写一个bash命令,用于删除所有与特定模式匹配的文件 - 在这种情况下,它是所有已经积累的旧vmware日志文件。

我尝试了这个命令:

find . -name vmware-*.log | xargs rm

然而,当我运行这个命令时,它在所有包含空格的文件夹上都出现了问题。是否有一种方法可以格式化文件路径,以便xargs将其作为带引号或正确转义的参数传递给rm?


跨贴:http://serverfault.com/questions/76031/shell-scripting-using-find-to-delete-files-matching-a-pattern - Dennis Williamson
7个回答

23

尝试使用:

find . -name vmware-*.log -print0 | xargs -0 rm

这使得 find 在每个文件名后输出一个 null 字符,并告诉 xargs 基于 null 字符而不是空格或其他分隔符来拆分名称。


9
不要使用xargs。find可以独立完成此操作: find . -name "vmware-*.log" -exec rm '{}' \;

3
尽可能避免启动额外的进程,特别是在这种情况下,您可能会向xargs提供过长的内容。请注意,find甚至有一个delete操作可用于代替-exec ...,但以这种方式进行自定义更容易。除非您使用像tcsh这样的旧shell,否则不必引用花括号。 - Cascabel
4
但是这会为每个文件单独启动一个rm进程,而不像xargs那样将多个文件名传递给rm,因此速度会更慢。 - JaakkoK
6
这就是为什么较新的find实现会有find -exec rm '{}' +这种用法,它会像xargs一样批量处理参数。 - ephemient
@jk:你对进程的看法是正确的。至于速度,总有例外,但根据我的经验,rm启动进程并不是主要瓶颈。如果你删除的文件足够多,以至于rm时间占优势,那么实际上是磁盘活动在拖慢你的速度。否则,无论如何,find时间才是最重要的(想想10000个文件中的5个匹配项)。 - Cascabel
@ephemient:好主意。我完全忘记了! - Cascabel

5

查看xargs-0标志;结合find-print0,您就可以设置了。

find . -name vmware-*.log -print0 | xargs -0 rm

4

GNU find

find . -name vmware-*.log -delete

1

find . -name vmware-*.log | xargs -i rm -rf {}

查找 . 目录下所有以 vmware- 开头,以 .log 结尾的文件,并将其删除。


0
为了避免在xargs中出现空格问题,我会使用-d选项并将换行符作为分隔符:
find . -name vmware-*.log | xargs -d '\n' rm

0
find -iname pattern

使用-iname进行模式搜索


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