Bash 在进行管道时何时使用xargs?
我是bash新手,我正在尝试理解Bash 在进行管道时何时使用xargs?,bash,xargs,Bash,Xargs,我是bash新手,我正在尝试理解xargs的用法,这对我来说还不清楚。例如: history | grep ls 我在这里搜索历史记录中的命令ls。在这个命令中,我没有使用xargs,它工作得很好 find /etc - name "*.txt" | xargs ls -l 在这一次,我不得不使用xargs,但我仍然无法理解其中的区别,我无法正确决定何时使用xargs,何时不使用。xargs(1)在读取非NUL分隔的输入时是危险的(损坏、可利用等) 如果您使用的是文件名,请改用find的-e
xargs
的用法,这对我来说还不清楚。例如:
history | grep ls
我在这里搜索历史记录中的命令ls
。在这个命令中,我没有使用xargs
,它工作得很好
find /etc - name "*.txt" | xargs ls -l
在这一次,我不得不使用xargs
,但我仍然无法理解其中的区别,我无法正确决定何时使用xargs
,何时不使用。xargs(1)在读取非NUL分隔的输入时是危险的(损坏、可利用等)
如果您使用的是文件名,请改用find
的-exec[command]{}+命令。
如果您可以获得NUL分隔的输出,请使用
xargs-0
简短回答:暂时避免xargs
。编写了几十个或数百个脚本后,返回到xargs
命令可以从参数(如rm bad\u示例
)获取输入,也可以从stdin
获取输入(不仅仅是rm-i后面问题的y也是这个\u bad\u
,还可以从读取答案
)。其他命令,如grep
和sed
将查找参数,当参数不显示输入时,切换到输入。您的
grep
示例可以从stdin中很好地阅读,没有什么特别需要的。您的
ls
需要find的输出作为参数xargs
只是扭转局面的一种方法。有关xargs的更多信息,请使用man xargs
。备选方案:
find /etc -name "*.txt" -exec ls -l {} \;
find /etc -name "*.txt" -ls
ls -l $(find /etc -name "*.txt" )
ls /etc/*.txt
首先,当您在/etc中有一个带有空格.txt的讨厌文件名时,请尝试看看这两个命令中的哪一个是最好的。GNU Parallel可以做与xargs相同的事情,但没有损坏的和可利用的“功能”
通过查看示例和浏览教程,您可以学习GNU并行。要回答您的问题,当您需要从一个命令获取输出并将其用作另一个命令的参数时,可以使用
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
,几乎总是有其他替代方法,学习这些方法会更好地为您服务。当您使用不带xargs
的管道时,实际数据会输入下一个命令。另一方面,将管道与xargs
一起使用时,实际数据将被视为下一个命令的参数。举一个具体的例子,假设您有一个文件夹,其中包含a.txt
和b.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
,而不是实际内容。@SaraHamad:通过将-print0
添加到cmd行,您可以从查找中获得以null结尾的字符串。检查你的手册页。(大多数新版本都有)如果要确保读取空分隔的输入,最好使用IFS=read-r-d''行来读取,不是更好吗?@DirkHerrmann您是对的。虽然我是为一般情况写的。根据你的评论,我删除了这个部分。作为“危险的(坏的,可利用的,等等)”,并不意味着它对于一次性脚本研磨几十个文件不是超级有用:)@JakubM。滚到尘土里去!底线是命令行的大小有一个限制。(这是一个硬编码数字,通常128KiB
)请参阅。当您的命令行超过该大小时,您可以选择使用xargs
,它将打破该大小并为您处理该命令。如果您觉得它有用,我将使用以下方法: