Jack Jack - 2 months ago 4
Bash Question

Counting number of files in multiple subdirectories from command line

I have a directory which contains a large number of subdirectories. Each subdirectory is named something like "treedir_xxx" where xxx is a number. I would like to run a command (preferably from the command line as I have no experience with batch scripts) that will count the number of files in each subdirectory named 'treedir_xxx' and write these numbers to a text file. I feel this should not be very difficult but so far I have been unsuccessful.

I have tried things like

find *treedir* -maxdepth 1 -type f | wc -l
however this just returns the total number of files rather than the number of files in each individual folder.


Instead of using find, use a for loop. I am assuming that you are using bash or similar since that is the most common shell on most of the modern Linux distros:

for i in treedir_*; do ls "$i" | wc -l; done

Given the following structure:

 |__ a
 |__ b
 |__ c
 |__ d
 |__ e
 |__ f

The result is:


You can get fancy and print whatever you want around the numbers:

for i in treedir_*; do echo $i: $(ls "$i" | wc -l); done


treedir_001: 3
treedir_002: 2
treedir_003: 1

This uses $(...) to get the output of a command as a string and pass it to echo, which can then print everything on one line.

for i in treedir_*; do echo $i; ls "$i" | wc -l; done



This one illustrates the use of multiple commands in a single loop.

for can be redirected to a file or piped just like any other command, so you can do

for i in treedir_*; do ls "$i" | wc -l; done > list.txt

or better yet

for i in treedir_*; do ls "$i" | wc -l; done | tee list.txt

The second version sends the output to the program tee, which prints it to standard output and also redirects it to a file. This is sometimes nicer for debugging than a simple redirect with >.

find is a powerful hammer, but not everything is a nail...