On 2020-02-20 20:46, Peng Yu wrote: > Hi, > > xargs by default does not put a multiple of m arguments (m is an > integer greater than 1) to the command line. But is there a way that I > can make sure only a multiple of m arguments are put the command line.
For my understanding: you have a program which would expect always 5 arguments from the initial input, right? For this, the input has to be structured so that it is really a multiple of M; otherwise, at least the last set of arguments is smaller than M. > For example, for something like the following command, I'd like to > make sure everytime there are 5 m arguments given to printf. But I > don't think xargs can guarantee so by default in the output of the > example. > > $ seq 1000000 | xargs printf '%s\t%s\t%s\t%s\t%s\n' > /tmp/1.txt > $ < /tmp/1.txt awk -v FS='\t' -e '!($1 && $2 && $3 && $4 && $5)' | wc -l > 105 In the above, xargs fills the command line for printf until the maximum command line length limit for each printf invocation. As it doesn't know about the "multiple-to-M" rule, some of the lines in /tmp/1.txt will just contain less than M elements. What about using "xargs -n 5 ..."? $ seq 1000000 | xargs -n 5 > /tmp/1.txt $ < /tmp/1.txt awk -e '!($1 && $2 && $3 && $4 && $5)' | wc -l 0 Well, obviously, this will execute 'echo' many times, and therefore is quite slow. Therefore, as you know the input, you can make an assumption of how many sets of M can be put into one command line. With the example from 'seq', it seems to be safe to put 2000 sets of M=5 into one command line: $ seq 1000000 | xargs -n $(( 5 * 2000 )) printf '%s\t%s\t%s\t%s\t%s\n' > /tmp/1.txt $ < /tmp/1.txt awk -e '!($1 && $2 && $3 && $4 && $5)' | wc -l 0 Have a nice day, Berny