2

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.

Jack
  • 131
  • 1
  • 11
  • do subdirectories contain just files or also directories as well? That is, how deep is the tree of dirs? – fedorqui Aug 09 '16 at 12:41
  • this could help ; http://stackoverflow.com/questions/15216370/how-to-count-number-of-files-in-each-directory – Mustafa DOGRU Aug 09 '16 at 12:43
  • Or better yet: http://stackoverflow.com/q/307015/2988730 – Mad Physicist Aug 09 '16 at 12:45
  • The subdirectories only contain files. – Jack Aug 09 '16 at 12:45
  • On a side note, all a shell script is (in it simplest form of course), is a list of the commands you ran on the command line, pasted into a text file and given execute permissions. Scripts are there to prevent you from having to type out the same dozen commands over and over, not to make your life harder (usually). – Mad Physicist Aug 09 '16 at 13:10

1 Answers1

5

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:

treedir_001
 |__ a
 |__ b
 |__ c
treedir_002
 |__ d
 |__ e
treedir_003
 |__ f

The result is:

3
2
1

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

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

gives

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

gives

treedir_001
3
treedir_002
2
treedir_003
1

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...

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • Excellent thank you, I included a '>fnum.txt' to write it to a text file, but this works brilliantly. – Jack Aug 09 '16 at 13:01