Linux – How to find folders over 1GB and execute another command in linux terminal

consolelinuxterminalunix

I want to find the folders which sizes are over 1GB and then if they are over then I want to erase them.

I found some commands like

find /some/path -type d -size +1G -exec ls {} \;

or

du -h /some/path | grep ^[0-9.]*G

or
(over 600M)

du -h /some/path/ | grep ^[6-9][0-9][0-9][0-9.]*M | sort

But these two commands are not really helping to me because the find command is not finding any folders although there are folders over 1GB but the linux thinks they are some small KB. Is there any command to achieve that?

Best Answer

A common problem when dealing with file/directory names is when they contain whitespace. *nix filepaths can even contain \n newlines. To get around all whitespace issues, you need to work with a null delimiter \x00.

#!/bin/bash
#
# Parameter 1 ("$1"):  Remove sub-directories from this directory
# Parameter 2 ("$2"):  Remove sub-directories larger than this many bytes 
#
# Example, To remove sub-directories bigger than 1 GB from your HOME directory
#   
#    script "$HOME"  $((2**30))     
#        
dir="$1"; shopt -s extglob; dir="${dir%%+(/)}"  # remove trailing / from directory path
[[ -d "$dir" ]] || { echo "\$1: directory NOT found: $1"; exit 1; }

size=$2  # size in bytes
[[ -z $2 || -n ${2//[0-9]} ]] && { echo "\$2: size-threshold must be numeric: $2"; exit 2; }

du -0b "$dir" |                        # output with \x00 as end-of-path
 sort -zrn  |                          # sort dirs,largest first
  awk -vRS="\x00" -vORS="\x00" -v"size=$size" -v"dir=$dir" -v"prev=\x00" '{
     if( $1<=size ) next               # filter by size; skip small dirs
     match( $0, "\x09" )               # find du TAB-delimiter           
     path = substr( $0, RSTART+1 )     # get directory path 
     if( path ~ "^"dir"/*$" ) next     # filter base dir; do not kill it! 
     match( path, "^" prev ".+" )      # print (ie. process) parent dirs only
     if( RSTART == 0 ) { print path }
     prev = path }' |
   xargs -0 -I{} echo rm -vr {}        # remove the `echo` to run live!!!!