具有多个参数的 xargs
我有一个源输入,input.txt,
a.txt
b.txt
c.txt
我想将这些输入输入到程序中,如下所示:
my-program --file=a.txt --file=b.txt --file=c.txt
所以我尝试使用xargs,但没有运气。
cat input.txt | xargs -i echo "my-program --file"{}
它给出了
my-program --file=a.txt
my-program --file=b.txt
my-program --file=c.txt
但我想要
my-program --file=a.txt --file=b.txt --file=c.txt
任何想法吗?
I have a source input, input.txt
a.txt
b.txt
c.txt
I want to feed these input into a program as the following:
my-program --file=a.txt --file=b.txt --file=c.txt
So I try to use xargs, but with no luck.
cat input.txt | xargs -i echo "my-program --file"{}
It gives
my-program --file=a.txt
my-program --file=b.txt
my-program --file=c.txt
But I want
my-program --file=a.txt --file=b.txt --file=c.txt
Any idea?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
不要听他们所有人的。 :) 看一下这个例子:
输出将是:
Don't listen to all of them. :) Just look at this example:
Output will be:
到目前为止给出的解决方案都没有正确处理包含空格的文件名。如果文件名包含 ' 或 ",有些甚至会失败。如果您的输入文件是由用户生成的,您应该为令人惊讶的文件名做好准备。
rel="noreferrer" >
GNU Parallel 可以很好地 程序接受命令行中容纳的尽可能多的参数:
观看介绍视频以了解更多信息:http: //www.youtube.com/watch?v=OpaiGYxkSuQ
None of the solutions given so far deals correctly with file names containing space. Some even fail if the file names contain ' or ". If your input files are generated by users, you should be prepared for surprising file names.
GNU Parallel deals nicely with these file names and gives you (at least) 3 different solutions. If your program takes 3 and only 3 arguments then this will work:
Or:
If, however, your program takes as many arguments as will fit on the command line:
Watch the intro video to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ
怎么样:
How about:
如果您使用两个 xargs 调用,那就更简单了:第一个将每一行转换为
--file=...
,第二个实际执行 xargs 操作 ->It's simpler if you use two xargs invocations: 1st to transform each line into
--file=...
, 2nd to actually do the xargs thing ->您可以使用
sed
在每行添加--file=
前缀,然后调用xargs
:You can use
sed
to prefix--file=
to each line and then callxargs
:这是一个使用 sed 处理三个参数的解决方案,但受到限制,因为它对每个参数应用相同的转换:
这是一个适用于两个参数的方法,但允许更大的灵活性:
Here is a solution using sed for three arguments, but is limited in that it applies the same transform to each argument:
Here's a method that will work for two args, but allows more flexibility:
我偶然发现了一个类似的问题,并找到了一个我认为比迄今为止提出的解决方案更好、更干净的解决方案。
我结束时的
xargs
语法是(对于您的示例):完整的命令行是:
它将像
完成一样工作(提供
input.txt
包含示例中的数据)。实际上,就我而言,我需要首先找到文件,并且还需要对它们进行排序,以便我的命令行如下所示:
一些可能不清楚的细节(它们不适合我):
some*pattern
必须加引号,否则 shell 会在传递给find
之前对其进行扩展。-print0
,然后是-z
,最后是-0
使用空分隔来确保正确处理带有空格或其他连线名称的文件。但请注意,我还没有对其进行深入测试。尽管它似乎正在发挥作用。
I stumbled on a similar problem and found a solution which I think is nicer and cleaner than those presented so far.
The syntax for
xargs
that I have ended with would be (for your example):with a full command line being:
which will work as if
was done (providing
input.txt
contains data from your example).Actually, in my case I needed to first find the files and also needed them sorted so my command line looks like this:
Few details that might not be clear (they were not for me):
some*pattern
must be quoted since otherwise shell would expand it before passing tofind
.-print0
, then-z
and finally-0
use null-separation to ensure proper handling of files with spaces or other wired names.Note however that I didn't test it deeply yet. Though it seems to be working.
这是因为
echo
打印换行符。尝试类似的东西It's because
echo
prints a newline. Try something likexargs 不是这样工作的。尝试:
xargs doesn't work that way. Try:
我正在寻找针对这个确切问题的解决方案,并得出了在中间编写脚本的结论。
要转换下一个示例的标准输出,请使用 -n '\n' 分隔符
示例:
要使此解决方案正常工作,您需要在这些参数 file1.txt 和 file2.txt 之间有一个空格,或者您选择的任何分隔符,再一个事情,在脚本中确保您检查 -f1 和 -f2,因为它们的意思是“取第一个单词并取第二个单词”,具体取决于找到的第一个分隔符的位置(分隔符可以是 ' ' ';' '.' 任何你想要的单引号之间。
添加任意数量的参数。
使用 xargs、cut 和一些 bash 脚本解决了问题。
干杯!
如果你想路过,我有一些有用的提示http://hongouru.blogspot.com
I was looking for a solution for this exact problem and came to the conclution of coding a script in the midle.
to transform the standard output for the next example use the -n '\n' delimeter
example:
For this solution to work you need to have a space between those arguments file1.txt and file2.txt, or whatever delimeter you choose, one more thing, inside the script make sure you check -f1 and -f2 as they mean "take the first word and take the second word" depending on the first delimeter's position found (delimeters could be ' ' ';' '.' whatever you wish between single quotes .
Add as many parameters as you wish.
Problem solved using xargs, cut , and some bash scripting.
Cheers!
if you wanna pass by I have some useful tips http://hongouru.blogspot.com
实际上,这相对简单:
... | sed 's/^/--prefix=/g' | sed 's/^/--prefix=/g' | xargs 回显 | xargs -I PARAMS your_cmd PARAMS
sed 's/^/--prefix=/g'
是可选的,以防您需要为每个参数添加 --prefix= 前缀。xargs echo
将参数行列表(每行一个参数)转换为单行中的参数列表,并且xargs -I PARAMS your_cmd PARAMS
允许您运行命令,将参数放置在您想要的位置。所以cat input.txt | sed 's/^/--file=/g' | sed 's/^/--file=/g' | xargs 回声 | xargs -I PARAMS my-program PARAMS 执行您需要的操作(假设 input.txt 中的所有行都很简单并且每行都符合单个参数值)。
Actually, it's relatively easy:
... | sed 's/^/--prefix=/g' | xargs echo | xargs -I PARAMS your_cmd PARAMS
The
sed 's/^/--prefix=/g'
is optional, in case you need to prefix each param with some --prefix=.The
xargs echo
turns the list of param lines (one param in each line) into a list of params in a single line and thexargs -I PARAMS your_cmd PARAMS
allows you to run a command, placing the params where ever you want.So
cat input.txt | sed 's/^/--file=/g' | xargs echo | xargs -I PARAMS my-program PARAMS
does what you need (assuming all lines within input.txt are simple and qualify as a single param value each).如果您不知道前面的文件数量,还有另一种好方法可以做到这一点:
There is another nice way of doing this, if you do not know the number of files upront:
大多数答案没有考虑到输入行中的某些字符可能会破坏
xargs
和/或不带引号的$(...)
。以下是一些可以正确完成工作(即稳健且高效)的解决方案。
1. PURE BASH
您可以将输入行加载到
bash
数组中,并使用参数扩展将--file=
添加到每个元素:警告!< /strong> 不要使用此方法为每个数组元素生成多个参数(例如
‑f
Spacexxx.txt)。
2. AWK | XARGS -0
您可以使用
awk
在每行前面添加--file=
并生成一个NUL
分隔的流,该流可以由xargs -0
安全处理:3。 SED | XARGS
如果您需要遵守POSIX:
Most answers don't take into account that some characters in the input lines can break
xargs
and/or unquoted$(...)
.Here are a few solutions that do the job correctly (i.e. robustly and efficiently).
1. PURE BASH
You can load the input lines into a
bash
array and prepend--file=
to each element with a parameter expansion:Warning! Don't use this method to generate more than one argument per array element (for e.g.
‑f
Spacexxx.txt
).2. AWK | XARGS -0
You can use
awk
to prepend--file=
to each line and generate aNUL
-delimited stream that can be safely processed byxargs -0
:3. SED | XARGS
If you ever need to be POSIX compliant:
还没有人提到从循环中回显,所以为了完整起见,我将其放入(这将是我的第二种方法, sed 是第一种):
Nobody has mentioned echoing out from a loop yet, so I'll put that in for completeness sake (it would be my second approach, the sed one being the first):
我发现了一个更直接的方法。您甚至可以根据自己的喜好自定义位置参数的顺序,如下面的演示所示。
这在您知道输入中参数的顺序和大小的情况下效果很好。
I discovered a more straightforward way. You can even customize the order of positional parameters to your liking, like in the demonstration below.
This works well in scenarios where you know the order and magnitude of arguments that are in the input.
旧的,但这是一个更好的答案:
gsed
只是 GNUsed
以确保语法与版本匹配。brew install gsed
或者只是sed
(如果您已经使用 GNU/Linux)...测试一下:
Old but this is a better answer:
gsed
is just GNUsed
to ensure syntax matches version.brew install gsed
or justsed
if you're on GNU/Linux already...Test it: