linux-具有多个参数的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
任何想法?
12个解决方案
83 votes
不要听所有的人:)看看这个例子:
echo argument1 argument2 argument3 | xargs -l bash -c 'echo this is first:$0 second:$1 third:$2' | xargs
输出将是
this is first:argument1 second:argument2 third:argument3
sauliux answered 2020-01-04T18:11:55Z
25 votes
到目前为止给出的解决方案都不能正确处理包含空格的文件名。 如果文件名包含“或”,有些甚至会失败。如果输入文件是由用户生成的,则应该准备好使用令人惊讶的文件名。
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}
要么:
(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={}
但是,如果您的程序接受的参数与命令行上的参数一样多:
(echo a1.txt; echo b1.txt; echo c1.txt;
echo d1.txt; echo e1.txt; echo f1.txt;) |
parallel -X my-program --file={}
观看介绍性视频以了解更多信息:[http://www.youtube.com/watch?v=OpaiGYxkSuQ]
Ole Tange answered 2020-01-04T18:11:31Z
18 votes
怎么样:
echo $'a.txt\nb.txt\nc.txt' | xargs -n 3 sh -c '
echo my-program --file="$1" --file="$2" --file="$3"
' argv0
yabt answered 2020-01-04T18:12:15Z
6 votes
您可以使用sed为每行添加--file=前缀,然后调用xargs:
sed -e 's/^/--file=/' input.txt | xargs my-program
Bart Sas answered 2020-01-04T18:12:35Z
5 votes
这是对三个参数使用sed的解决方案,但局限性在于它对每个参数应用相同的转换:
cat input.txt | sed 's/^/--file=/g' | xargs -n3 my-program
这是一种适用于两个args的方法,但具有更大的灵活性:
cat input.txt | xargs -n 2 | xargs -I{} sh -c 'V="{}"; my-program -file=${V% *} -file=${V#* }'
maharvey67 answered 2020-01-04T18:12:59Z
2 votes
如果使用两次xargs调用会更简单:第一个将每行转换为--file=...,第二个实际执行xargs事情->
$ cat input.txt | xargs -I@ echo --file=@ | xargs echo my-program
my-program --file=a.txt --file=b.txt --file=c.txt
jjo answered 2020-01-04T18:13:19Z
2 votes
我偶然发现了一个类似的问题,并找到了一个解决方案,我认为它比迄今为止提供的解决方案更好,更干净。
我以-print0结尾的语法为(以您的示例为例):
xargs -I X echo --file=X
完整的命令行为:
my-program $(cat input.txt | xargs -I X echo --file=X)
就像
my-program --file=a.txt --file=b.txt --file=c.txt
已完成(假设-print0包含您示例中的数据)。
实际上,就我而言,我需要首先找到文件,并且还需要对其进行排序,因此我的命令行如下所示:
my-program $(find base/path -name "some*pattern" -print0 | sort -z | xargs -0 -I X echo --files=X)
一些细节可能不清楚(对我来说不是):
必须引用-print0,因为否则shell会在传递给-z之前对其进行扩展。
-print0,然后-z,最后-0使用空分隔来确保正确处理带空格或其他有线名称的文件。
但是请注意,我尚未对其进行深入测试。 虽然它似乎正在工作。
Adam Badura answered 2020-01-04T18:14:19Z
1 votes
这是因为echo打印换行符。 尝试类似
echo my-program `xargs --arg-file input.txt -i echo -n " --file "{}`
aioobe answered 2020-01-04T18:14:39Z
1 votes
xargs不能那样工作。 尝试:
myprogram $(sed -e 's/^/--file=/' input.txt)
Burton Samograd answered 2020-01-04T18:14:59Z
1 votes
我一直在寻找针对此确切问题的解决方案,并得出在中间编写脚本的结论。
要转换下一个示例的标准输出,请使用-n'\ n'分隔符
例:
user@mybox:~$ echo "file1.txt file2.txt" | xargs -n1 ScriptInTheMiddle.sh
inside the ScriptInTheMidle.sh:
!#/bin/bash
var1=`echo $1 | cut -d ' ' -f1 `
var2=`echo $1 | cut -d ' ' -f2 `
myprogram "--file1="$var1 "--file2="$var2
为使此解决方案起作用,您需要在脚本文件中的这些参数file1.txt和file2.txt或您选择的任何分隔符之间留一个空格,还要确保在脚本中检查-f1和-f2,因为它们的意思是“采用 第一个单词,然后取第二个单词”,取决于找到的第一个分隔符的位置(分隔符可以是''';''。根据需要添加任意数量的参数。
使用xargs,cut和一些bash脚本解决了问题。
干杯!
如果您想通过,我有一些有用的提示[http://hongouru.blogspot.com]
HoNgOuRu answered 2020-01-04T18:15:46Z
0 votes
还没有人提到从循环中回显,因此出于完整性考虑,我将其放入(这将是我的第二种方法,sed是第一种):
for line in $(< input.txt) ; do echo --file=$line ; done | xargs echo my-program
conny answered 2020-01-04T18:16:06Z
0 votes
实际上,这相对容易:
cat input.txt | sed 's/^/--file=/g' | xargs echo | xargs -I PARAMS my-program PARAMS
cat input.txt | sed 's/^/--file=/g' | xargs echo | xargs -I PARAMS my-program PARAMS是可选的,以防您需要为每个参数加上--prefix =前缀。
cat input.txt | sed 's/^/--file=/g' | xargs echo | xargs -I PARAMS my-program PARAMS将参数行列表(每行一个参数)转换为一行中的参数列表,并且xargs -I PARAMS your_cmd PARAMS允许您运行命令,将参数放置在所需的位置。
因此cat input.txt | sed 's/^/--file=/g' | xargs echo | xargs -I PARAMS my-program PARAMS可以满足您的需求(假设input.txt中的所有行都很简单,并且每个行都可以视为一个参数值)。
Moshe Bixenshpaner answered 2020-01-04T18:16:44Z