I am using this script to count files on my directory and sub-directories:

for i in $(find . -type d) ; do 
  printf "$i %s\t" ;
  ( find $i -type f | wc -l ) ; 

This script works fine. What I really want it to do is to print only the directories that contain more than 31 files.

5 Answers 5



find . -type d -exec sh -c '[ $(find "$1" -type f | wc -l) -gt 31 ]' _ {} \; -print

I'd advise using the -maxdepth restriction on the second find, otherwise you might find some surprising results. The command won't work with names containing newlines.


Replace the line:

( find $i -type f | wc -l ) ; 

With this:

FILES=$( find $i -type f | wc -l ); 

Then you could ask for it:

if [ "$FILES" -gt 31 ] ; then
  • i tried this but i am getting an error Nov 13, 2014 at 15:25

This should to it using -gt:

for i in $(find . -type d) ; do   
  NUM=$( find $i -type f | wc -l );
  if [[ $NUM -gt 31 ]]; then 
        echo "$i $NUM" ;   

With zsh, to print the paths of directories that contain at least 32 entries other than . and ..:

print -rC1 -- **/*(ND/e['()(($#)) $REPLY/*(NDY32[32]oN)'])


  • **/*: recursive globbing
  • (...): glob qualifiers
  • N: Nullglob: don't complain if there's no match
  • D: Dotglob: don't skip hidden files
  • /: restrict to files of type directory
  • e['code']: filter files for which the evaluation of code returns true.
  • ()(($#)) args: anonymous function that returns true if the number of its arguments is non-zero
  • $REPLY: the file (here directory) currently being considered in code.
  • $REPLY/*: the files in there. Replace with $REPLY/**/* to also count files in subdirs. Add ^/ to the qualifier if you don't want to count files of type directory, or . to restrict to regular files only to the exclusion of any other type of file like your -type f would do.
  • Y32: stop looking after the 32nd one has been found:
  • [32]: select the 32nd in that list:
  • oN: don't bother sorting that list.

Note that the current working directory itself is not considered.


A solution using 's array :

x=( * )
((${#x[@]} > 31)) && printf '%s\n' *

You must log in to answer this question.

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