0

Running wc -l (line count) individually on a file gives:

λ wc -l pacman_Qemq.txt
235 pacman_Qemq.txt

But running ls | xargs wc -l gives:

λ ls | xargs wc -l
  242409 pacman_database.tar.bz2
     235 pacman_Qemq.txt
     235 pacman_Qem.txt
     807 pacman_Qeq.txt
     807 pacman_Qe.txt
     376 pacman_Qmq.txt
    2276 pacman_Qnq.txt
    2276 pacman_Qn.txt
    2652 pacman_Qq.txt
    2652 pacman_Qsq.txt
    2652 pacman_Q.txt
  257377 total

How can this be? Why did the total show up? Why are the entries aligned? Shouldn't xargs be running wc -l individually on each file?

Interestingly, wc -l * produces the same result.

1 Answer 1

5

By default, xargs will pass as many parameters on a single command line as it can - usually up to the shell limit of (IIRC) 256 characters. So the command you're using, ls | xargs wc -l, is functionally equal to wc -l *. The behavior I believe you're expecting is for xargs to run wc once for each file, which can be produced by adding the -n option, ls | xargs -n 1 wc -l.

2
  • +1 - although the argument length limit is likely significantly larger than 256 characters. See for example What is a canonical way to find the actual maximum argument list length? Commented Jan 5, 2020 at 14:36
  • Note the "functionally equal" commands that you mention are only functionally equal if the number of files in the current directory is small. Also, using xargs -n 1 wc -l on the right hand side would not work as soon as a filename contains a space, tab or newline. Commented Jan 5, 2020 at 15:16

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.