Home > Software design >  How to count xargs arguments
How to count xargs arguments

Time:09-22

I'm piping a large file (~5M lines) into xargs that I'm processing in batches using -L to limit to max-lines per command. The command I'm calling with xargs requires not only the arguments (one argument per line in the input file), but additionally a count of the number of arguments I am passing it as the first argument.

e.g. I have a file, numbers.txt containing the English words for the first 17 numbers, one per line.

cat numbers.txt | xargs -n 3 echo prints the following:

one two three
four five six
seven eight nine
ten eleven twelve
thirteen fourteen fifteen
sixteen seventeen

As expected echo is called with 3 arguments, the max-lines limit, on each invocation except the last because we only have two lines remaining.

What I want is to call my target command with a count of the arguments passed followed by the actual args.

Extending the preceding example, cat numbers.txt | xargs -n 3 sh -c 'mycommand "$#" "$@"' almost gives what I want. Strangely (at least to me), the first argument is missing from both $@ and $#.

That is, cat numbers.txt | xargs -n 3 sh -c 'echo "$#" "$@"' prints

2 two three
2 five six
2 eight nine
2 eleven twelve
2 fourteen fifteen
1 seventeen

rather than

3 one two three
3 four five six
3 seven eight nine
3 ten eleven twelve
3 thirteen fourteen fifteen
2 sixteen seventeen

which is what I would expect.

Why is this happening? How can I arrive at the expected output? I'm not married to this approach, if there is something simpler I could do please suggest.

CodePudding user response:

You need a placeholder to fill in $0 so the first argument becomes $1.

<numbers.txt xargs -n 3 sh -c 'echo "$#" "$@"' sh

CodePudding user response:

You need to add an extra argument when passing arguments to sh -c, because the first argument is treated as $0, not an actual argument.

xargs -n 3 sh -c 'echo "$#" "$@"' sh
  • Related