3

I want to find all folders (within a folder) which are less than 100mb large and delete them. I actually don't want to use a bash script. But probably there is some neat one-line-loop possibility to do this. But unfortunately my shell knowledge isn't that good

What I've tried

 du -sh * | grep -E "^[0-9]{1,2}M" | xargs -0 rm

This won't work since the output of du -sh * | grep _E ".." seems to be one single string.

What I also have tried is

find . -maxdepth 1 -type d -size 100M [-delete]

But I guess the -size flag isn't what I'm looking for

  • What's wrong with -size flag? – Edward Torvalds Jan 27 '15 at 3:37
  • @edwardtorvalds I've tried -size 100M and it did not show up anything – Brettetete Jan 27 '15 at 3:50
2

The simple approach is to find all directories, get their size and delete them if they are under a given threshold:

find . -maxdepth 1 -type d | 
  while read dir; do [ $(du -s "$dir") -le 102400 ] && rm -f "$dir"; done

However, that will fail on directory names containing newlines or other strange characters. A safer syntax is:

find . -maxdepth 1 -type d -print0 | while IFS= read -r -d '' dir; do
    [ $(du -s "$dir") -le 102400 ] && rm -f "$dir"
done

Since this will process subdirectories before their parents, by the time dir1 is processed, dir2 and dir3 will already have been deleted so its size will be below the threshold and it too will be removed. Whether or not you actually want this will depend on what exactly you are trying to do.


This, however, is a simplistic approach. Consider the following scenario:

$ tree -h
.
`-- [4.0K]  dir1
    |-- [4.0K]  dir2
    |   `-- [ 80M]  file1
    `-- [4.0K]  dir3
        `-- [ 80M]  file2

3 directories, 2 files

Here, we have 2 subdirectories under dir1, each containing an 80M file. The command above will first find dir1 whose size is >100M so it will not be deleted. It will then find dir1/dir2 and dir1/dir3 and delete both of them since they are <100M. The final result will be an empty dir1 whose size, of course, will be <100M since it is empty.

So, this solution will work fine if you only have a single level of subdirectories. If you have more complex file structures, you need to think about how you want to deal with that. One approach would be to use -depth which ensures that subdirectories are shown first:

find . -depth -maxdepth 1  -type d -print0 | while IFS= read -r -d '' dir; do
    [ $(du -s "$dir") -le 102400 ] && rm -f "$dir"
done

This way, dir1 will be processed after dir2 and dir3 so it will be empty, fail the threshold and be deleted as well. Whether or not you want this will depend on what exactly you are trying to do.

  • ...and all this without even considering that you can have hardlinked files in that directory trees... ;-) </ducks> – Rmano Mar 2 '15 at 17:21
  • @Rmano exactly. Let alone sparse files and the like. This is a fairly complex issue actually. – terdon Mar 2 '15 at 17:26
  • Yes. The main problem is that the phrase "folder with size lesser than 100Mbyte" is not well defined, really. – Rmano Mar 2 '15 at 18:23
0

Using du with flag -h to do value comparison is usually a bad idea.

The command you are looking for is:

find . -maxdepth 1 -type d | grep -v ^\\.$ | xargs -n 1 du -s | while read size name ; do if [ $size -gt 104857600 ] ; then echo rm -rf $name ; fi done

Explanation:

  • find . -maxdepth 1 -type d finds all subdirectories of the current directory
  • grep -v ^\\.$ excludes the current directory (.)
  • xargs -n 1 passes them one by one to the next command
  • du -s provides the summary (i.e. total) space of the files in that directory
  • while read size name ... done executes a loop over its input, reading the size and the name of each directory
  • the rest is more or less self explanatory.

Once you are happy with the command remove the echo before rm -rf

  • I think the variant I'd use would be while read -r -d '' size dir; do [[ $size -lt 100 ]] && echo rm -rf "$dir"; done < <(find -depth -type d -exec du -0sm {} \;) – steeldriver Jan 27 '15 at 3:39

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.