Show number of files in several directory trees using Shell
We already know how to Show number of files in a single directory tree using Shell, but what if given a directory, we would like to know the number of files in each one of its subdirectories separately?
We assume the same directory structure as in that other article:
groups/ all.txt people/ John.txt Jane.txt maskots/ Foo.txt Bar.txt other -> maskots
In the previous article we reached this solution for a single directory:
$ find groups -type f | wc -l
Now we need to go over all the subdirectories and run the above expression for each one of them.
Wildecard expansion
In our first attempt we use the wildecard expansion groups/* to list all the item in the "groups" directory. We go over it in a for loop and for each iteration we echo the name of the thing and call the above expression.
$ for x in groups/*; do (echo $x; find $x -type f | wc -l) ; done groups/all.txt 1 groups/maskots 2 groups/other 0 groups/people 2
The output includes the directories 'maskots' and 'people' as we wanted, but it also includes "all.txt" which is a plain file and 'other' which is a symbolic link.
Find with backtick
We can use find here too with type directory and maxdepth 1, but that will return the root directory as well:
$ find groups -maxdepth 1 -type d groups groups/maskots groups/people
In this case we can also include mindepth to make sure only the right depth is included:
$ find groups -maxdepth 1 -mindepth 1 -type d groups/maskots groups/people
Using this we can now write:
$ for x in `find groups -maxdepth 1 -mindepth 1 -type d`; do (echo $x; find $x -type f | wc -l) ; done groups/maskots 2 groups/people 2
Using result interpolation
Instead of the backticks ``, it is usually better to write $(). The result is the same:
$ for x in $(find groups -maxdepth 1 -mindepth 1 -type d ); do (echo $x; find $x -type f | wc -l) ; done groups/maskots 2 groups/people 2
Published on 2017-11-21