使用find和xargs执行批量文件操作

linux下有很多小工具,它们本身的功能很单一,但是结合起来经常会产生强大的效果,例如find和xargs的结合。

find命令是用来对指定目录进行查找的;xargs的功能是将标准输入里的文本作为指定命令的参数去执行。xargs命令可能我们平常用的不多,下面先看一个简单的例子:

[leconte@localhost ~]$ xargs wc -l
a.php
b.php
 
  9 a.php
  3 b.php
 12 总计

a.php和b.php是我们手工输入进去的,它们是我文件系统中已存在的文件,输入完毕后按Ctrl+D发送结束字符后xargs就开始执行,它首先将标准输入中的内容根据空格空行等分隔符分开,然后统一作为wc -l 的参数执行,即相当于执行了wc -l a.php b.php这个命令。

find命令的标准输出通常是符合条件的一些文件的列表,通过管道即可转化为后续程序的标准输入。若后续程序是xargs,那么这个文件列表即可作为xargs指定命令的参数执行,这样即可实现对于文件的批量操作。

例如要删除执行目录下所有.tmp文件,用find和xargs命令就可以这样写:

find . -type f -name ‘*.tmp’ | xargs rm -v

例如:

[leconte@localhost test]$ find . -type f -name '*.tmp'
./b.tmp
./c.tmp
./tmp/d.tmp
./tmp/e.tmp
./a.tmp
[leconte@localhost test]$ find . -type f -name '*.tmp' | xargs rm -v
已删除“./b.tmp”
已删除“./c.tmp”
已删除“./tmp/d.tmp”
已删除“./tmp/e.tmp”
已删除“./a.tmp”

它实际执行的命令是rm -v ./b.tmp ./c.tmp ./tmp/d.tmp ./tmp/e.tmp ./a.tmp。但是有了find和xargs的结合就将查找和删除这两步合成一步,方便快捷。

此外,find和xargs结合还经常用于在指定目录下进行文本内容搜索的场景,例如在一个源代码树中查找包含printf的C代码:

find ~/codeproject/ -type f -name ‘*.c’ | xargs grep -i ‘printf’