查找空目录

我需要为给定的目录列表找到空目录。 有些目录里面有目录。

如果内部目录也是空的,我可以说 main 目录是空的,否则它就不是空的。

我该怎么测试?

例如:

A>A1(file1),A2 this is not empty beacuse of file1
B>B1(no file) this is empty
C>C1,C2 this is empty
76970 次浏览

Check whether find <dir> -type f outputs anything. Here's an example:

for dir in A B C; do
[ -z "`find $dir -type f`" ] && echo "$dir is empty"
done

您可以使用以下命令:

find . -type d -empty

我创建了一个简单的结构如下:

测试/
Test/test2/
Test/test2/test2.2/
Test/test3/
Test/test3/file

test/test3/file包含一些垃圾文本。

发出 find test -empty将返回“ test/test2/test2.2”作为唯一的空目录。

一个简单的方法就是,

$ [ "$(ls -A /path/to/direcory)" ] && echo "not empty" || echo "its empty"

还有,

if [ "$(ls -A /path/to/direcory)" ]; then
echo "its not empty"
else
echo "empty directory"

这在一定程度上取决于您希望如何处理空目录。当我希望 删除树中的所有空目录(比如 test目录)时,我使用下面的命令。

find test -depth -empty -delete

关于上面的命令需要注意的一点是 它还会删除空文件,因此使用 D 型选项可以避免这一点。

find test -depth -type d -empty -delete

删除 -delete以查看匹配的文件和目录。

If your definition of an empty directory tree is that it contains no files then you be able to stick something together based on whether find test -type f returns anything.

find是一个伟大的实用程序,RTFM 很早就经常了解它能做多少: -)

这个递归函数似乎可以解决这个问题:

# Bash
findempty() {
find ${1:-.} -mindepth 1 -maxdepth 1 -type d | while read -r dir
do
if [[ -z "$(find "$dir" -mindepth 1 -type f)" ]] >/dev/null
then
findempty "$dir"
echo "$dir"
fi
done
}

给出这个目录结构示例:

.
|-- dir1/
|-- dir2/
|   `-- dirB/
|-- dir3/
|   `-- dirC/
|       `-- file5
|-- dir4/
|   |-- dirD/
|   `-- file4
`-- dir5/
`-- dirE/
`-- dir_V/

运行该函数的结果将是:

./dir1
./dir5/dirE/dir_V
./dir5/dirE
./dir5
./dir2/dirB
./dir2

which misses /dir4/dirD. If you move the recursive call findempty "$dir" after the fi, the function will include that directory in its results.

find . -name -type d -ls |awk '($2==0){print $11}'
find directory -mindepth 1 -type d -empty -delete

这是我觉得最有趣的版本。如果从 目录内部执行,它将删除下面的所有空目录(如果目录只包含空目录,则认为该目录为空)。

Mindeep 选项防止在目录碰巧为空时删除目录本身。

只要找到空磁盘

为了找到空目录(正如问题标题中指定的那样) ,mosg's answer是正确的:

find -type d -empty

但是 -empty可能不适用于非常老的 find版本(例如 HP-UX)。如果是这种情况,请参阅下面 目录是空的吗?小节中描述的技术。

Delete empty dirs

这有点棘手: 假设目录 MyDir包含空目录。删除这些空目录后,MyDir将变成一个空目录,也应该删除。因此,我使用带有选项 --parents(或 -p)的命令 rmdir,它在可能的情况下也会删除父目录:

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

在旧版本的 find中,还不支持语句 +,因此可以使用 ;:

find -type d -empty -exec rmdir -vp --ignore-fail-on-non-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
    

    一种变化:

    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
    

    解说:

    • find -prune is similar than find -maxdepth 0 using less characters
    • find -type d只打印目录
    • 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 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
    

    注意: 空目录和不存在的目录之间没有区别(甚至当提供的路径是一个文件时也是如此)。

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

    这个魔术的灵感来自于2007年发布的 NixCraft 的文章Andrew Taylor在2008年回答,Gr8can8dian在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 ..."
    

    注意: 当目录不存在时,ls返回 $?=2,但是文件和空目录之间没有区别。

那么 rmdir *呢? 这个命令在非空目录下会失败。

find . -type d -empty

查找并列出当前树中的空目录和子目录。 例如,产生的空目录和子目录列表:

./2047
./2032
./2049
./2063
./NRCP26LUCcct1/2039
./NRCP26LUCcct1/2054
./NRCP26LUCcct1/2075
./NRCP26LUCcct1/2070

不对目录进行任何操作。它们只是简单地列出。 这对我有用。

如果目录为空(或不存在) ,下面的命令返回1,否则返回0(因此可以用 shell 脚本中的 !反转返回代码) :

find $dir -type d -prune -empty -exec false {} +