Linux 带有多个参数的 xargs
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3770432/
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
xargs with multiple arguments
提问by Howard
I have a source input, input.txt
我有一个源输入,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.
所以我尝试使用xargs,但没有运气。
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?
任何的想法?
采纳答案by Ole Tange
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 Paralleldeals 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:
GNU Parallel 可以很好地处理这些文件名,并为您提供(至少)3 种不同的解决方案。如果您的程序需要 3 个且只有 3 个参数,那么这将起作用:
(echo a1.txt; echo b1.txt; echo c1.txt;
echo a2.txt; echo b2.txt; echo c2.txt;) |
parallel -N 3 my-program --file={1} --file={2} --file={3}
Or:
或者:
(echo a1.txt; echo b1.txt; echo c1.txt;
echo a2.txt; echo b2.txt; echo c2.txt;) |
parallel -X -N 3 my-program --file={}
If, however, your program takes as many arguments as will fit on the command line:
但是,如果您的程序需要尽可能多的参数以适合命令行:
(echo a1.txt; echo b1.txt; echo c1.txt;
echo d1.txt; echo e1.txt; echo f1.txt;) |
parallel -X my-program --file={}
Watch the intro video to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ
观看介绍视频以了解更多信息:http: //www.youtube.com/watch?v=OpaiGYxkSuQ
回答by aioobe
It's because echo
prints a newline. Try something like
这是因为echo
打印换行符。尝试类似
echo my-program `xargs --arg-file input.txt -i echo -n " --file "{}`
回答by Bart Sas
You can use sed
to prefix --file=
to each line and then call xargs
:
您可以使用sed
前缀--file=
到每一行,然后调用xargs
:
sed -e 's/^/--file=/' input.txt | xargs my-program
回答by Burton Samograd
xargs doesn't work that way. Try:
xargs 不能那样工作。尝试:
myprogram $(sed -e 's/^/--file=/' input.txt)
回答by yabt
How about:
怎么样:
echo $'a.txt\nb.txt\nc.txt' | xargs -n 3 sh -c '
echo my-program --file="" --file="" --file=""
' argv0
回答by HoNgOuRu
I was looking for a solution for this exact problem and came to the conclution of coding a script in the midle.
我正在为这个确切的问题寻找解决方案,并得出了在 midle 中编写脚本的结论。
to transform the standard output for the next example use the -n '\n' delimeter
要转换下一个示例的标准输出,请使用 -n '\n' 分隔符
example:
例子:
user@mybox:~$ echo "file1.txt file2.txt" | xargs -n1 ScriptInTheMiddle.sh
inside the ScriptInTheMidle.sh:
!#/bin/bash
var1=`echo | cut -d ' ' -f1 `
var2=`echo | cut -d ' ' -f2 `
myprogram "--file1="$var1 "--file2="$var2
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.
为了让这个解决方案起作用,你需要在这些参数 file1.txt 和 file2.txt 之间留一个空格,或者你选择的任何分隔符,还有一件事,在脚本中确保你检查 -f1 和 -f2,因为它们的意思是“把第一个单词并取第二个单词”,具体取决于找到的第一个分隔符的位置(分隔符可以是 ' ' ';' '.' 单引号之间您希望的任何内容。添加任意数量的参数。
Problem solved using xargs, cut , and some bash scripting.
使用 xargs、cut 和一些 bash 脚本解决了问题。
Cheers!
干杯!
if you wanna pass by I have some useful tips http://hongouru.blogspot.com
如果你想路过我有一些有用的提示http://hongouru.blogspot.com
回答by maharvey67
Here is a solution using sed for three arguments, but is limited in that it applies the same transform to each argument:
这是一个将 sed 用于三个参数的解决方案,但其局限性在于它对每个参数应用相同的转换:
cat input.txt | sed 's/^/--file=/g' | xargs -n3 my-program
Here's a method that will work for two args, but allows more flexibility:
这是一种适用于两个 args 的方法,但具有更大的灵活性:
cat input.txt | xargs -n 2 | xargs -I{} sh -c 'V="{}"; my-program -file=${V% *} -file=${V#* }'
回答by sauliux
dont listen to all of them :) just look at this example:
不要听他们所有人:) 看看这个例子:
echo argument1 argument2 argument3 | xargs -l bash -c 'echo this is first:this is first:argument1 second:argument2 third:argument3
second: third:' | xargs
output will be
输出将是
for line in $(< input.txt) ; do echo --file=$line ; done | xargs echo my-program
回答by conny
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):
还没有人提到从循环中回显,所以为了完整起见,我将其放入(这将是我的第二种方法,sed 是第一种方法):
xargs -I X echo --file=X
回答by Adam Badura
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):
xargs
我已经结束的语法是(对于你的例子):
my-program $(cat input.txt | xargs -I X echo --file=X)
with a full command line being:
完整的命令行是:
my-program --file=a.txt --file=b.txt --file=c.txt
which will work as if
这将工作好像
my-program $(find base/path -name "some*pattern" -print0 | sort -z | xargs -0 -I X echo --files=X)
was done (providing input.txt
contains data from your example).
已完成(提供input.txt
包含您示例中的数据)。
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.
some*pattern
必须引用,否则 shell 会在传递到find
.-print0
,然后-z
最后-0
使用空分隔来确保正确处理带有空格或其他连线名称的文件。
Note however that I didn't test it deeply yet. Though it seems to be working.
但是请注意,我还没有对其进行深入测试。虽然它似乎有效。