How*_*ard 53 linux bash shell xargs command-line-arguments
我有一个源输入,input.txt
a.txt
b.txt
c.txt
Run Code Online (Sandbox Code Playgroud)
我想将这些输入提供给程序,如下所示:
my-program --file=a.txt --file=b.txt --file=c.txt
Run Code Online (Sandbox Code Playgroud)
所以我尝试使用xargs,但没有运气.
cat input.txt | xargs -i echo "my-program --file"{}
Run Code Online (Sandbox Code Playgroud)
它给
my-program --file=a.txt
my-program --file=b.txt
my-program --file=c.txt
Run Code Online (Sandbox Code Playgroud)
但我想要
my-program --file=a.txt --file=b.txt --file=c.txt
Run Code Online (Sandbox Code Playgroud)
任何的想法?
小智 85
不要听他们所有人:)只看这个例子:
echo argument1 argument2 argument3 | xargs -l bash -c 'echo this is first:$0 second:$1 third:$2' | xargs
Run Code Online (Sandbox Code Playgroud)
输出将是
this is first:argument1 second:argument2 third:argument3
Run Code Online (Sandbox Code Playgroud)
Ole*_*nge 25
到目前为止,给出的解决方案都没有正确处理包含空格的文件名.如果文件名包含'或',有些甚至会失败.如果您的输入文件是由用户生成的,那么您应该为令人惊讶的文件名做好准备.
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}
Run Code Online (Sandbox Code Playgroud)
要么:
(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={}
Run Code Online (Sandbox Code Playgroud)
但是,如果您的程序采用了与命令行相同的参数:
(echo a1.txt; echo b1.txt; echo c1.txt;
echo d1.txt; echo e1.txt; echo f1.txt;) |
parallel -X my-program --file={}
Run Code Online (Sandbox Code Playgroud)
观看介绍视频以了解更多信息:http://www.youtube.com/watch?v = OpaiGYxkSuQ
小智 18
怎么样:
echo $'a.txt\nb.txt\nc.txt' | xargs -n 3 sh -c '
echo my-program --file="$1" --file="$2" --file="$3"
' argv0
Run Code Online (Sandbox Code Playgroud)
您可以使用sed前缀--file=到每一行,然后调用xargs:
sed -e 's/^/--file=/' input.txt | xargs my-program
Run Code Online (Sandbox Code Playgroud)
如果您使用两个 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
Run Code Online (Sandbox Code Playgroud)
这是一个使用sed用于三个参数的解决方案,但其局限性在于它对每个参数应用相同的转换:
cat input.txt | sed 's/^/--file=/g' | xargs -n3 my-program
Run Code Online (Sandbox Code Playgroud)
这是一个适用于两个args的方法,但允许更多的灵活性:
cat input.txt | xargs -n 2 | xargs -I{} sh -c 'V="{}"; my-program -file=${V% *} -file=${V#* }'
Run Code Online (Sandbox Code Playgroud)
我偶然发现了一个类似的问题,并找到了一个我认为比迄今为止提出的解决方案更好、更干净的解决方案。
xargs我结束的语法是(对于您的示例):
xargs -I X echo --file=X
Run Code Online (Sandbox Code Playgroud)
完整的命令行是:
my-program $(cat input.txt | xargs -I X echo --file=X)
Run Code Online (Sandbox Code Playgroud)
这就像
my-program --file=a.txt --file=b.txt --file=c.txt
Run Code Online (Sandbox Code Playgroud)
已完成(提供input.txt包含示例中的数据)。
实际上,就我而言,我需要首先找到文件,并且还需要对它们进行排序,因此我的命令行如下所示:
my-program $(find base/path -name "some*pattern" -print0 | sort -z | xargs -0 -I X echo --files=X)
Run Code Online (Sandbox Code Playgroud)
一些可能不清楚的细节(它们不适合我):
some*pattern必须加引号,否则 shell 会在传递到 之前对其进行扩展find。-print0,然后-z最后-0使用空分隔来确保正确处理带有空格或其他连线名称的文件。但请注意,我还没有对其进行深入测试。尽管它似乎正在发挥作用。
| 归档时间: |
|
| 查看次数: |
63976 次 |
| 最近记录: |