Finding empty directories UNIX

后端 未结 12 638
心在旅途
心在旅途 2020-12-07 14:11

I need to find empty directories for a given list of directories. Some directories have directories inside it.

If inside directories are also empty I can say main di

12条回答
  •  长情又很酷
    2020-12-07 14:46

    Just find empty dirs

    In order to just find empty directories (as specified in the question title), the mosg's answer is correct:

    find -type d -empty
    

    But -empty may not be available on very old find versions (this is the case of HP-UX for example). If this is your case, see the techniques described in below section Is a directory empty?.

    Delete empty dirs

    This is a bit tricky: Suppose a directory MyDir contains empty directories. After removing these empty directories, MyDir will become an empty directory and should also be removed. Therefore I use the command rmdir with the option --parents (or -p) that also removes parent directories when possible:

    find -type d -empty -exec rmdir -vp --ignore-fail-on-non-empty {} +
    

    On older find version the statement + is not yet supported, therefore you may use ; instead:

    find -type d -empty -exec rmdir -vp --ignore-fail-on-non-empty {} `;`
    

    Is a directory empty?

    Most of these answers explain how to check if a directory is empty. Therefore I provide here the three different techniques I know:

    1. [ $(find your/dir -prune -empty) = your/dir ]

      d=your/dir
      if [ x$(find "$d" -prune -empty) = x"$d" ]
      then
        echo "empty (directory or file)"
      else
        echo "contains files (or does not exist)"
      fi
      

      a variation:

      d=your/dir
      if [ x$(find "$d" -prune -empty -type d) = x"$d" ]
      then
        echo "empty directory"
      else
        echo "contains files (or does not exist or is not a directory)"
      fi
      

      Explanation:

      • find -prune is similar than find -maxdepth 0 using less characters
      • find -type d prints directories only
      • find -empty prints the empty directories and files

        > mkdir -v empty1 empty2 not_empty
        mkdir: created directory 'empty1'
        mkdir: created directory 'empty2'
        mkdir: created directory 'not_empty'
        > touch not_empty/file
        > find empty1 empty2 not_empty -prune -empty
        empty1
        empty2
        
    2. (( ${#files} ))

      This trick is 100% bash but invokes (spawns) a sub-shell. The idea is from Bruno De Fraine and improved by teambob's comment. I advice this one if you use bash and if your script does not have to be portable.

      files=$(shopt -s nullglob dotglob; echo your/dir/*)
      if (( ${#files} ))
      then 
        echo "contains files"
      else 
        echo "empty (or does not exist or is a file)"
      fi
      

      Note: no difference between an empty directory and a non-existing one (and even when the provided path is a file).

    3. [ $(ls -A your/dir) ]

      This trick is inspired from nixCraft's article posted in 2007. Andrew Taylor answered in 2008 and gr8can8dian in 2011.

      if [ "$(ls -A your/dir)" ]
      then
        echo "contains files"
      else
        echo "empty (or does not exist or is a file)"
      fi
      

      or the one-line bashism version:

      [[ "$(ls -A your/dir)" ]] && echo "contains files" || echo "empty or ..."
      

      Note: ls returns $?=2 when the directory does not exist. But no difference between a file and an empty directory.

提交回复
热议问题