关于linux命令“xargs”的使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18104585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
About the usage of linux command "xargs"
提问by BlackMamba
I have some file like
我有一些像
love.txt
loveyou.txt
in directory useful
; I want to copy this file to directory /tmp
.
在目录中useful
;我想将此文件复制到目录/tmp
。
I use this command:
我使用这个命令:
find ./useful/ -name "love*" | xargs cp /tmp/
but is doesn't work, just says:
但不起作用,只是说:
cp: target `./useful/loveyou.txt' is not a directory
when I use this command:
当我使用这个命令时:
find ./useful/ -name "love*" | xargs -i cp {} /tmp/
it works fine,
它工作正常,
I want to know why the second works, and more about the usage of -i cp {}
.
我想知道为什么第二个有效,以及更多关于-i cp {}
.
回答by choroba
xargs
puts the words coming from the standard input to the end of the argument list of the given command. The first form therefore creates
xargs
将来自标准输入的单词放在给定命令的参数列表的末尾。因此,第一种形式创建
cp /tmp/ ./useful/love.txt ./useful/loveyou.txt
Which does not work, because there are more than 2 arguments and the last one is not a directory.
这不起作用,因为有两个以上的参数,最后一个不是目录。
The -i
option tells xargs
to process one file at a time, though, replacing {}
with its name, so it is equivalent to
该-i
选项告诉一次xargs
处理一个文件,但替换{}
为其名称,因此等效于
cp ./useful/love.txt /tmp/
cp ./useful/loveyou.txt /tmp/
Which clearly works well.
这显然运作良好。
回答by Nathan Fellman
The first example will do this:
第一个示例将执行此操作:
cp /tmp/ love.txt loveyou.txt
Which can't be done, since they attempt to copy the directory /tmp
and the file love.txt
to the file loveyou.txt
.
这是无法完成的,因为他们试图将目录/tmp
和文件复制love.txt
到文件loveyou.txt
.
In the second example, -i
tells xargs
to replace every instance of {}
with the argument, so it will do:
在第二个例子中,-i
告诉用参数xargs
替换每个实例{}
,所以它会这样做:
cp love.txt /tmp/
cp loveyou.txt /tmp/
回答by Erik A. Brandstadmoen
When using the xargs -i
command, {}
is substituted with each element you find. So, in your case, for both "loveyou.txt" and "love.txt", the following command will be run:
使用该xargs -i
命令时,{}
将替换为您找到的每个元素。因此,在您的情况下,对于“loveyou.txt”和“love.txt”,将运行以下命令:
cp ./useful/loveyou.txt /tmp/
cp ./useful/love.txt /tmp/
if you omit the {}
, all the elements you find will automatically be inserted at the end of the command, so, you will execute the nonsensical command:
如果省略{}
,您找到的所有元素将自动插入到命令的末尾,因此,您将执行无意义的命令:
cp /tmp/ ./useful/loveyou.txt ./useful/love.txt
回答by Graham Griffiths
xargs appends the values fed in as a stream to the end of the command - it does not run the command once per input value. If you want the same command run multiple times - that is what the -i cp {} syntax is for.
xargs 将作为流输入的值附加到命令的末尾 - 它不会为每个输入值运行一次命令。如果您希望多次运行相同的命令 - 这就是 -i cp {} 语法的用途。
This works well for commands which accept a list of arguments at the end (e.g. grep) - unfortunately cp is not one of those - it considers the arguments you pass in as directories to copy to, which explains the 'is not a directory' error.
这适用于在末尾接受参数列表的命令(例如 grep) - 不幸的是 cp 不是其中之一 - 它认为您传入的参数作为要复制到的目录,这解释了“不是目录”错误.
回答by jlliagre
You might avoid xargs that way:
你可以这样避免 xargs :
find ./useful/ -name "love*" -exec sh -c 'cp "$@" /tmp' sh {} +
回答by user3581131
find ./useful/ -name "love*" | xargs cp -t /tmp/