Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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.

share|improve this question

2 Answers 2

up vote 2 down vote accepted

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>
share|improve this answer
    
Good point about how xargs is breaking up args, on whitespace boundaries, not line boundaries (although lines are special for arguments like -L and hence implicitly for -I). –  BeeOnRope Jan 23 at 3:42
    
@BeeOnRope: even with -L, xargs breaks arguments on wordspace. The line count specifies the number of lines containing arguments but the lines are not otherwise treated specially. –  rici Jan 23 at 17:29
    
Right, that's why I said "lines are special" not that xargs changes the way it breaks up arguments, but that it does use lines to initially chunk the input into invocations, then proceeds to break up on whitespace as usual. –  BeeOnRope Jan 23 at 19:34
    
echo -e "line 1\nline 2\nline 3" | parallel echo :{}: –  Ole Tange Jan 24 at 8:06

Convert newlines into \nul terminators, then use xargs -0

$ echo -ne 'line 1\nline 2\nline 3\n' | tr '\n' '\0' | xargs -0 -Ix echo x DONE
line 1 DONE
line 2 DONE
line 3 DONE
share|improve this answer
    
As above, I got the same output already without the tr and -0 (it is not needed here). The issue is that I want it all on one line: line 1 DONE line 2 DONE ... –  BeeOnRope Jan 25 at 1:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.