Linux – xargs substition of more than one argument

bashlinuxxargs

By default xargs will concatenate many lines of its input and pass then to the specified command. For example:

echo -e 'line 1\nline 2\nline 3' | xargs echo 

results in

line 1 line 2 line 3

Since the arguments are sent to a single echo command (within the limits of the command line length).

Sometimes you want to use replacement string to put the arguments somewhere else in the command, rather than the end:

echo -e 'line 1\nline 2\nline 3' | xargs -Ix echo x DONE
line 1 DONE
line 2 DONE
line 3 DONE

Now, xargs only substituted one argument per each echo invocation, because as the man page says "-I implies -L 1…". That's probably the right behavior for a typical case, but is there any way to override it, so I get line 1 line 2 line 3 DONE as the output?

Please note that my example is illustrative only – I'm not very interested in non-xargs ways of tacking this issue.

Best Answer

I don't know of an xargs option which will do that, but you can achieve something similar with an invocation of bash -c:

$ echo -e "line 1\nline    2\nline 3" | xargs bash -c 'echo "${@}" DONE' _
line 1 line 2 line 3 DONE

Note that xargs does not provide the lines as arguments, even if you specify -L. You might want to use -d to specify that new-line separates items (gnu xargs only, I believe). Contrast the following:

$ echo -e "line 1\nline    2\nline 3" |
  xargs bash -c 'printf "<%s>\n" "${@}" DONE' _
<line>
<1>
<line>
<2>
<line>
<3>
<DONE>

$ echo -e "line 1\nline    2\nline 3" |
  xargs -d\\n bash -c 'printf "<%s>\n" "${@}" DONE' _
<line 1>
<line    2>
<line 3>
<DONE>
Related Question