Split line into 3 separate arguments using xargs

brucezepplin picture brucezepplin · Apr 18, 2015 · Viewed 10k times · Source

If I have the following:

$ printf '%s\n' "${fa[@]}"

1 2 3
4 5 6
7 8 9

where each line is a new array element. I want to be able to split the element by space delimiter and use the result as 3 separate parameters and pipe into xargs.

For example the first element is:

1 2 3

where using xargs I want to pass 1, 2 and 3 into a simple echo command such as:

$ echo $0
1
4
7

$ echo $1
2
5
8

$ echo $2
3
9
6

So I have been trying doing this in the following way:

printf '%s\n' "${fa[@]}" | cut -d' ' -f1,2,3 | xargs -d' ' -n 3 bash -c 'echo $0'

which gives:

1
2
3 4
5
6 7
8
9 10

which aside from the strange line ordering - trying xargs -d' ' -n 3 bash -c 'echo $0' does not print out the first "element" of each line i.e.

$ echo $0
1
4
7

but rather prints them all out.

What I am asking is, for each element, how do I split the line into three separate arguments that can be referenced via xargs?

Thanks!

Answer

Tim Rijavec picture Tim Rijavec · Apr 19, 2015

You were going in the right direction

To declare an array:

fa=('1 2 3' '4 5 6' '7 8 9')

To achieve what you want:

printf '%s\n' "${fa[@]}" | xargs -n 3 sh -c 'echo call_my_command --arg1="$1" --arg2="$2" --arg3="$3"' argv0

this will echo you the following lines (change command that is passed to the xargs accordingly)

call_my_command --arg1=1 --arg2=2 --arg3=3
call_my_command --arg1=4 --arg2=5 --arg3=6
call_my_command --arg1=7 --arg2=8 --arg3=9

If I just add your answer and changed it a little we'll get the following

printf '%s\n' "${fa[@]}" | cut -d' ' -f1,2,3 | xargs -n 3 bash -c 'echo $0 $1 $2'

notice missing -d' ' in xargs, this option is not available in some versions of xargs.