Is it possible to return a combined word count with wc only for certain files (like .txt files, for example) in a series of directories?

  • 6
    cat them all and pipe the result to wc ? Mar 25, 2017 at 20:12

3 Answers 3


With GNU wc (at least), you can combine the results of find with wc as such:

find folder/ -name '*.txt' -print0 |   wc -w --files0-from=-

This gives you all the power of find (a bit overkill if you just want to find all files ending with .txt to be honest) and it handles even the strangest filenames (containing newlines for example).

  • 1
    On MacOS, you can replace wc with gwc (after you have installed coreutils with brew install coreutils). May 12, 2021 at 12:12

Do I understand your situation correctly? So, you're saying that you are in a folder say Documents, and you have several folders within this folder, so you change directory (cd) into that directory an want to count how many .txt files are deep into that directory in every sub-folder?

If that's what you mean, then this is how you do it:

$ ls -R *.txt | wc -l

ls = list. -R = recursively every subfolder *.txt = any number of any character ending in .txt

| = pass to.

wc -l = count how many.

  • 1
    This doesn't do what you think it does. The *.txt would be expanded by the shell into a space delimited list of .txt files found in the current working directory. If no .txt files exist, ls would likely (depending on shell options) get passed *.txt, but since ls doesn't do pattern matching, it would be looking for a file litterarly called *.txt in the current working directory.
    – user60101
    Mar 26, 2017 at 2:16
  • See how bash processes commands and file name expansion. ls *.txt is generally equivlient to echo *.txt. The shell is doing the expansion first, ls is essentially just printing the result.
    – user60101
    Mar 26, 2017 at 3:50
  • Oh, so what the asker wanted was the number of lines in every text file recursively, and not the number of text files recursively?
    – xyz123
    Mar 26, 2017 at 4:06
  • Yes, but the *.txt is processed, before the ls -R. Your command doesn't count the number of .txt files recursivly. It counts the number of .txt files in the current working directory and fails on some edge cases. ls -R | grep .txt | wc -l would be closer, but again doesn't handle newlines well, etc... lgeorget's awnser does
    – user60101
    Mar 26, 2017 at 4:54
  • I guess as a better example, consider that you have two subdirectories called 1abc and 2abc. ls -R *abc wouldn't print files ending in abc, it would recursivly print everything found in 1abc and 2abc
    – user60101
    Mar 26, 2017 at 5:18

Here is a good one-liner via xargs I just made - tested on macOS:

find . | grep -E "(.*\.js.*|.*\.txt|.*\.css|.*\.htm.*|.*\.sh|.*\.scss|.*\.md|.*\.java|.*\.conf|.*\.yaml)" | sed "s/^/\"/" | sed "s/$/\"/" | xargs -J thefile wc thefile

This handles spaces in filenames. Maybe swap -J for -Y in Linux? Lawn mower cut my Ethernet to my linux box so I can't test there presently.

You must log in to answer this question.

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