linux - Find directories containing a certain number of files

08
2014-07
  • Paul Ruane

    Was hoping I would be able to do this with the find command but I can see no test in the manual for doing what I want. I would like to be able to find any directories in the working directory that contain less-than, more-than or exactly the count I specify.

    find . -filecount +10 # any directory with more than 10 entries
    find . -filecount 20 # any directory with exactly 20 entries
    

    But alas there is no such option.

  • Answers
  • terdon

    You could try this, to get the sub directory names and the number of files/directories they contain:

    find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \;
    

    If you want to do the same for all sub directories (recursive find) use this instead:

    find . -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \;
    

    To select those directories that have exactly 10 files:

    find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
      awk '$NF==10'
    

    10 or more:

    find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
     awk '$NF>=10'
    

    10 or less:

    find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
     awk '$NF<=10'
    

    If you want to keep only the directory name (for example of you want to pipe it to another process downstream as @evilsoup suggested) you can use this:

    find . -maxdepth 1 -type d -exec bash -c "echo -ne '{}\t'; ls '{}' | wc -l" \; | 
     awk -F"\t" '$NF<=10{print $1}'
    
  • september

    Try this:

    [ `find . | wc -l` -eq 10 ] && echo "Found"

    [ `find . | wc -l` -gt 10 ] && echo "Found"

    [ `find . | wc -l` -lt 10 ] && echo "Found"

    In this examples you can check if CURRENT directory contains exactly 10, more then 10 and less then 10 files/directories. If you need to check bunch of directories, just use loop.


  • Related Question

    Problems excluding directories in a Linux find
  • GreenMatt

    Trying to exclude a set of directories from a find is driving me nuts! What I want to do is look for all .java files in a directory tree, but ignore all those in test directories. So, I've tried:

    find . -name "*.java" -not -path "test"
    

    and

    find . -name "*.java" -path "test" -prune
    

    and several variations thereof. However - depending on the variation - I either get all the java files (including those in test directories), or none of them. I looked at other questions here on SU (e.g. this one and this one), but either they don't address my situation, or I'm missing something.

    I'm using gnu find 4.2.27 (fwiw, on centos 5.5 w/ gnu bash 3.2.25).

    Edit: Sorry, I should have originally specified that I need to do a

    -exec grep blah {} \;
    

    so piping through grep -v won't work for me in this situation.


  • Related Answers
  • cYrus

    This should work:

    find -path '*/test/*' -prune -o -name '*.java' -exec grep blah {} \;
    
  • jonsca

    Consolidating the above-mentioned tips, this searches for PHP files recursively but excludes several directories and then zips them up.

    find -name locallibs -prune -o -name libs -prune -o -name wiki -prune -o -name tmp -prune -o -name '*.php' -exec zip all.zip {} \;