I need to run an executable a large number of times, each time with two command line arguments. I've used to use xargs for this purpose, but lately I've been made aware of the existence of GNU parallel, which in principle seems like a better tool (more features, more up-to-date, more extensive documentation, etc.).

Also, a strong selling point for me was the claim that it can be used as "a drop in replacement for xargs" (https://www.gnu.org/software/parallel/history.html). However, I'm having a bit of trouble with that last point.

Say that I have a text file, args.txt, with several lines, where each line contains two numbers separated by a space, for example:

1 2
7 9
11 13

I want to run my program, run, once for each line (i.e., once for each pair of arguments). With xargs I would do

cat args.txt | xargs -n2 run

where -n2 indicates that xargs should pass 2 arguments to run at each invocation. xargs then interprets each number as one argument, so each line of args.txt is interpreted as two arguments.

However, when I try using parallel as a drop-in replacement for xargs in the case above, I get different behaviour.

To illustrate, I will use the following small python script in place of my program run:


import sys
print([x for x in sys.argv[1:]])

Now, with xargs I get:

> cat args.txt | xargs -n2 python printer.py

['1', '2']
['7', '9']
['11', '13']

while with parallel I get

> cat args.txt | parallel -n2 python printer.py

['1 2', '7 9']
['11 13']

So while xargs calls the python script with the individual (space-separated) numbers as arguments, parallel interprets instead each line as a single argument, meaning that for example at the first call, the first argument is "1 2" instead of just "1".

I'm a little bit confused by this, as I had expected parallel to work as a drop-in replacement for xargs, but apparently it's a bit more subtle than that. I suppose my question is how I should use parallel to achieve the same thing that I'm doing with xargs, but I'm also just curious about why there is a difference in behaviour here, and if it's intentional.

  • 1
    You could try cat args.txt | parallel --colsep ' ' python printer.py if separator is always one space. Regexp is also possible.
    – stoney
    Oct 5, 2022 at 13:51
  • This works nicely, thanks! I actually tried --colsep before, but I also kept -n2, which didn't work. But your suggestion does exactly what I want. If you post it as an answer I'll mark it as the accepted solution.
    – Tor
    Oct 6, 2022 at 11:26

2 Answers 2


You have hit one of the few incompatibilities between xargs and parallel which is by design.

GNU Parallel will make sure the input is quoted as a single argument, whereas xargs will not. It was one of the original driving forces for writing the first versions of GNU Parallel.

$ echo '9" nails in 10" boxes' | xargs echo
9 nails in 10 boxes
$ echo '9" nails in 10" boxes' | parallel echo
9" nails in 10" boxes

You can, however, force GNU Parallel not to quote the input:

cat args.txt | parallel python printer.py {=uq=}

This will take one line from args.txt and insert it in the command without quoting it.

(Version 20190722 or later).

Another option is to split the columns on a single space (as mentioned in the comments):

cat args.txt | parallel --colsep ' ' python printer.py

Or white space:

cat args.txt | parallel --colsep '\s+' python printer.py

(Version 20100822 or later).


Parallel reads the input a line at a time, unlike xargs which reads words.

You can achieve the same result like this:

> sed 's/\s\+/\n/g' args.txt | parallel -n2 python printer.py

Here, the sed tool converts all groups of white-space into a line break.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .