GNU工具系列:xargs

xargs是GNU fileutils提供的一个命令,fileutils包含find, locate,xargs和updatedb。

xargs的作用是读取标准输入,构造成命令行参数,并执行命令。通常配合find的输出使用。

xargs [option…] [command [initial-arguments]]

所谓命令行参数的形式如下:

cp a.c b.c

其中cp是命令,其余为参数,以空格分隔。

那么什么时候需要xargs呢?比如有如下需求,将a目录下的所有*.c文件复制到b目录。我们
首先需要找出所有的*.c文件,比如可以通过find a -name "*.c"命令。这个命令输出结果是一
行行的文件名,如:

./src/a.c
./src/test/b.c
./src/example/c.c
...

很自然的,我们会想到,如果可以把输出转成一行,我们就能直接使用cp命令将多个文件复制
到b目录了。即cp ./src/a.c ./src/test/b.c ./src/example/c.c ./b

查看xargs命令的格式:xargs [options] [command [initial-arguments]]。xargs的语义就是将输入转换
command的参数。按照这个格式,我们先写下:

find a -name "*.c" | xargs echo

翻译一下就是将find的输出(多行文件名)转换成echo命令的参数(以空格为区分)。相当于:

echo ./src/a.c ./src/test/b.c ./src/example/c.c

直接将echo换成cp命令还存在一个问题,xargs是将参数附在command的后面,但是cp需要将参数
加在cp和目标目录的中间,即cp xxx ./b。好在xargs提供了-I参数,允许替换命令位置:

find a -name "*.c" | xargs -I {} cp {} ./b

其中{}相当于占位符,告诉xargs将参数放在这里,也可以用任意其他字符串代替。
执行完后,文件确实正确复制到了b目录,但是实际过程却有些不一样。由于使用了-I参数,导致
xargs每次读1行,上述命令并不是用cp将多个文件复制到b目录,而是执行了多次cp命令,每次只
复制一个文件。

为什么会这样呢?回到一开始说的,xargs的作用是将输入转换成命令行参数,而转换的方式是由
一系列参数控制的。比如:

  • -d:指定分隔符,默认是换行符\n,这也是多行输入被转换成了一行的原因。我们也可以指定其他
    的分隔符号。
  • -n:指定数量,即一组包含多少个参数。比如如果指定n等于2,那么相当于每次只有两个参数被
    提取。如果参数大于2,那么会重复执行command命令。

那如果我就要一次性读入所有参数怎么做呢?可以通过多个xargs组合来实现。

find a -name "*.c" | xargs | xargs -I x cp x ./b

第一次xargs将所有行转换成空格分隔的一行,然后第二次xargs全部读入,替换cp的参数x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值