关于linux命令“xargs”的用法

时间:2013-08-07 13:23:13

标签: linux shell

我有一些像

这样的文件
love.txt  
loveyou.txt 
目录useful中的

;我想将此文件复制到目录/tmp

我使用这个命令:

find ./useful/ -name "love*" | xargs cp /tmp/

但是不起作用,只是说:

cp: target `./useful/loveyou.txt' is not a directory

当我使用此命令时:

 find ./useful/ -name "love*" | xargs -i cp {} /tmp/

它工作正常,

我想知道为什么第二个有效,更多关于-i cp {}的用法。

6 个答案:

答案 0 :(得分:21)

xargs将来自标准输入的单词放入给定命令的参数列表的末尾。因此,第一种形式创建

cp /tmp/ ./useful/love.txt ./useful/loveyou.txt

哪个不起作用,因为有两个以上的参数,最后一个不是目录。

-i选项告诉xargs一次处理一个文件,将{}替换为其名称,因此等同于

cp ./useful/love.txt    /tmp/
cp ./useful/loveyou.txt /tmp/

这显然效果很好。

答案 1 :(得分:11)

使用xargs -i命令时,{}将替换为您找到的每个元素。因此,在您的情况下,对于“loveyou.txt”和“love.txt”,将运行以下命令:

cp ./useful/loveyou.txt /tmp/
cp ./useful/love.txt /tmp/

如果省略{},您找到的所有元素将自动插入命令的末尾,因此,您将执行无意义的命令:

cp /tmp/ ./useful/loveyou.txt ./useful/love.txt

答案 2 :(得分:4)

第一个例子将执行此操作:

cp /tmp/ love.txt loveyou.txt

无法完成,因为他们尝试将目录/tmp和文件love.txt复制到文件loveyou.txt

在第二个示例中,-i告诉xargs用参数替换{}的每个实例,所以它会这样做:

cp love.txt /tmp/
cp loveyou.txt /tmp/

答案 3 :(得分:4)

xargs将作为流输入的值附加到命令的末尾 - 它不会为每个输入值运行一次命令。如果您希望多次运行相同的命令 - 这就是-i cp {}语法的用法。

这适用于最后接受参数列表的命令(例如grep) - 不幸的是cp不是其中之一 - 它认为你传递的参数是要复制到的目录,这解释了'不是目录'错误。

答案 4 :(得分:3)

find ./useful/ -name "love*" | xargs cp -t /tmp/

答案 5 :(得分:1)

你可以这样避免xargs:

find ./useful/ -name "love*" -exec sh -c 'cp "$@" /tmp' sh {} +