xargs with multiple arguments

Viewed 105088

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?

14 Answers

It's simpler if you use two xargs invocations: 1st to transform each line into --file=..., 2nd to actually do the xargs thing ->

$ cat input.txt | xargs -I@ echo --file=@ | xargs echo my-program
my-program --file=a.txt --file=b.txt --file=c.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 the xargs -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:

my-program $(find . -name '*.txt' -printf "--file=%p ")

Old but this is a better answer:

cat input.txt | gsed "s/\(.*\)/\-\-file=\1/g" | tr '\n' ' ' | xargs my_program

# i like clean one liners gsed is just gnu sed to ensure syntax matches version brew install gsed or just sed if your on gnu linux already...

test it:

cat input.txt | gsed "s/\(.*\)/\-\-file=\1/g" | tr '\n' ' ' | xargs echo my_program
Related