关于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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:29:26  来源:igfitidea点击:

About the usage of linux command "xargs"

linuxshell

提问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

xargsputs 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 -ioption tells xargsto 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 /tmpand the file love.txtto the file loveyou.txt.

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

In the second example, -itells xargsto 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 -icommand, {}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/