2

How can I find and delete subdirectories that contain less than 100 files (or 200 files)?

I have found and used the following command, but don't know how to delete the listed subdirectories. (I have over 1000 of such folders and subdirectories, can't do it by hand).

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

thank you!

1
  • 4
    What if a directory contains no files but does contain more than 200 subdirectories? Should that be removed? How about links? Do they count as files? What if a directory contains few files but has a subdirectory with many? Should it be kept? Please edit your question and clarify what you need. The command you're using will fail on dile names with whitespace and will also delete parent directories whose children you might want to keep.
    – terdon
    Sep 6, 2016 at 10:00

3 Answers 3

0

Below I have included the answer to your question, however I would like to stress that you need to exercise extreme caution with this command. The output of your original awk is being piped into rm -rf, this means that this command is forcibly removing all the folders listed.

Make sure that you are very careful as to where you run this because, if run in most places, this could cause massive problems or irreparable damage to the system.


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

The output of your original command is being piped into xarge rm -rf, xargs is converting the original output into arguments for another program, in this case, rm.

Excerpt from the manpage for rm for the two switches being used:

       -f, --force
          ignore nonexistent files, never prompt

       -r, -R, --recursive
          remove directories and their contents recursively

Piping directly into rm wouldn't work as it does not expect to receive file or folder names in that format.

3
  • 1
    @countermode there are indeed problems with this answer since it won't work as expected for file names with spaces in them, but the filtering is being done. Note the awk '$NF<=10'.
    – terdon
    Sep 6, 2016 at 9:49
  • @terdon Thanks for pointing that out, I will add that now.
    – Hatclock
    Sep 6, 2016 at 9:57
  • Sorry for that, I experimented with the command but removed the awk part in order to see the full output. Sep 6, 2016 at 10:07
0

In zsh:

for d (**/*(Nod/))
  ()(($#)) $d/*(NDoN.[100]) ||
  ()(($#)) $d/*(ND/Y1) ||
  rm -rf -- $d 

Would delete the non-hidden directories that do not contain 100 regular files or more and do not contain subdirectories. That's processed depth-first so directories get a chance to be deleted if they have subdirectories that are to be deleted themselves.

-1

Below script is dirty yet working solution.

Run this script on testing env before applying on working computer as it will delete the contents

cd desired_directory
for i in `find . -maxdepth 1 -type d | grep "/"`
do
   cd $i;
   j=`echo \`ls -l | wc -l\` | bc`
   [ $j -lt "100" ] && echo "Lesser than 100 files/directories in $i"
   cd ../
done

Here, you have to replace the echo statement with either rm -rf or mv.

1
  • 1
    1) not sure about cd .., you'd rather use (cd $i, ... ) inside for loop. 2) OP say less, replace -gt by -lt
    – Archemar
    Sep 6, 2016 at 11:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.