xargs in shell - Forget the for loop

2019/11/23

If you supply the shell command xargs with the right commands, it will function the same way as a for loop. But more like a functional map command.

Normally xargs will execute a provided command once and append everything from pipe as arguments:

> echo 1 2 3 4 | xargs echo These arguments were provided:
These arguments were provided: 1 2 3 4

Adding the parameters -n 1 will execute the command time for each 1 piped arguments.

> echo 1 2 3 4 | xargs -n 1 echo Run for each argument:
Run for each argument: 1
Run for each argument: 2
Run for each argument: 3
Run for each argument: 4

If your variable argument for the command is the last argument, this will work fine.

But if not. xargs has the parameter -I. Unfortunately this parameter make the command work different:

> echo 1 2 3 4 | xargs -n 1 -I {} echo Run with {} as argument
Run with 1 2 3 4 as argument

-n 1 no longer works…

There is a work around.

A delimiter has to be given. In the example it will be space: -d " ". However, -d messes up the delimiter by not striping aways other white spaces. When using echo, a newline character will be put at the end of the arguments. We can remove any newline from the xargs input by using an additional before our intended xargs:

> echo 1 2 3 4 | xargs echo -n | xargs -d " " -I {} echo Run with {} as argument
Run with 1 as argument
Run with 2 as argument
Run with 3 as argument
Run with 4 as argument

Here, the part xargs echo -n will take all piped incoming arguments and print them space separated and -n will prevent a newline character from being printed at the end.