Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get xargs to word-split placeholder {}

Tags:

bash

xargs

(Though word splitting has a specific definition in Bash, in this post it means to split on spaces or tabs.)

Demonstrating the question using this input to xargs,

$ cat input.txt
LineOneWithOneArg
LineTwo WithTwoArgs
LineThree WithThree Args
LineFour  With  Double  Spaces

and this Bash command to echo the arguments passed to it,

$ bash -c 'IFS=,; echo "$*"' arg0 arg1 arg2 arg3
arg1,arg2,arg3

notice how xargs -L1 word-splits each line into multiple arguments.

$ xargs <input.txt -L1 bash -c 'IFS=,; echo "$*"' arg0
LineOneWithOneArg
LineTwo,WithTwoArgs
LineThree,WithThree,Args
LineFour,With,Double,Spaces

However, xargs -I{} expands the whole line into {} as a single argument.

$ xargs <input.txt -I{} bash -c 'IFS=,; echo "$*"' arg0 {}
LineOneWithOneArg
LineTwo WithTwoArgs
LineThree WithThree Args
LineFour  With  Double  Spaces

While this is perfectly reasonable behavior for the vast majority of cases, there are times when word-splitting behavior (the first xargs example) is preferred.

And while xargs -L1 can be seen as a workaround, it can only be used to place arguments at the end of the command line, making it impossible to express

$ xargs -I{} command first-arg {} last-arg

with xargs -L1. (That is of course, unless command is able to accept arguments in a different order, as is the case with options.)

Is there any way to get xargs -I{} to word-split each line when expanding the {} placeholder?

like image 220
mxxk Avatar asked Nov 17 '18 04:11

mxxk


1 Answers

Sort of.

echo -e "1\n2 3" | xargs sh -c 'echo a "$@" b' "$0"

Outputs:

a 1 2 3 b

ref: https://stackoverflow.com/a/35612138/1563960

Also:

echo -e "1\n2 3" | xargs -L1 sh -c 'echo a "$@" b' "$0"

Outputs:

a 1 b
a 2 3 b
like image 191
webb Avatar answered Nov 11 '22 05:11

webb