管道何时使用xargs?

时间:2016-02-23 22:05:02

标签: bash xargs

我是bash的新手,我正在努力了解xargs的用法,这对我来说仍然不太清楚。例如:

history | grep ls

我在这里搜索历史记录中的ls命令。在这个命令中,我没有使用xargs,它工作正常。

find /etc - name "*.txt" | xargs ls -l

我这个,我必须使用xargs,但我仍然无法理解差异,我无法正确决定何时使用xargs,何时不能。

5 个答案:

答案 0 :(得分:6)

要回答您的问题,当您需要从一个命令获取输出并将其用作另一个命令的参数时,可以使用xargs。在第一个示例中,grep从标准输入中获取数据,而不是作为参数。因此,不需要xargs

xargs从标准输入获取数据并执行命令。默认情况下,数据作为参数附加到命令的末尾。但是,它可以插入任何位置,使用占位符进行输入。传统的占位符是{};使用它,您的示例命令可能会写为:

find /etc -name "*.txt" | xargs -I {} ls -l {}

如果/etc中有3个文本文件,您将获得每个文件的完整目录列表。当然,您可以轻松编写ls -l /etc/*.txt并省去麻烦。

另一个示例允许您重命名这些文件,并要求占位符{}使用两次。

find /etc -name "*.txt" | xargs -I {} mv {} {}.bak

这些都是不好的例子,只要你有一个包含空格的文件名就会中断。您可以通过告诉find将文件名与空字符分开来解决这个问题。

find /etc -print0 -name "*.txt" | xargs -I {} -0 mv {} {}.bak

我个人认为,使用xargs几乎总有其他选择,学习这些内容会更好。

答案 1 :(得分:3)

简短回答:暂时避免使用xargs。当您编写了数十个或数百个脚本时,请返回xargs

命令可以从参数(例如rm bad_example)获取输入,也可以从stdin获取输入(不仅仅是rm -i is_this_bad_too之后问题的y,还有read answer })。其他命令(如grepsed)将查找参数,当参数不显示输入时,切换到输入。
你的grep示例可以很好地从stdin读取,没有什么特别需要 您的ls需要find的输出作为参数。 xargs只是扭转局面的一种方式。使用man xargs了解有关xargs的更多信息。备选方案:

find /etc -name "*.txt" -exec ls -l {} \;
find /etc -name "*.txt" -ls
ls -l $(find /etc -name "*.txt" )
ls /etc/*.txt

首先尝试在/ etc中有a nasty filename with spaces.txt时查看哪个命令最佳。

答案 2 :(得分:0)

读取非NUL分隔的输入时,

xargs(1)是危险的(损坏,可利用等)。

如果您正在处理文件名,请改用find的-exec [command] {} +。 如果您可以获得NUL分隔的输出,请使用xargs -0

答案 3 :(得分:0)

GNU Parallel可以和xargs一样,但没有破坏和可利用的功能#34;。

您可以通过查看示例http://www.gnu.org/software/parallel/man.html#EXAMPLE:-Working-as-xargs--n1.-Argument-appending并阅读教程http://www.gnu.org/software/parallel/parallel_tutorial.html

来学习GNU Parallel

答案 4 :(得分:0)

使用不带xargs的管道时,实际数据将输入到下一个命令中。另一方面,当使用带有xargs的管道时,实际数据将作为下一条命令的参数查看。举一个具体的例子,假设您有一个包含a.txtb.txt的文件夹。 a.txt仅包含一行' hello world!',而b.txt仅是空白。

如果愿意

ls | grep txt

您最终将获得输出。

a.txt
b.txt

但是,如果您这样做

ls | xargs grep txt

您将一无所获,因为文件a.txt和b.txt都不包含单词 txt 。如果命令是

ls | xargs grep hello

您会得到

hello world!

这是因为在xargs中,ls给出的两个文件名被作为参数而不是实际内容传递给grep