我有一些像
这样的文件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 {}
的用法。
答案 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 {} +