查找空目录UNIX


90

我需要找到给定目录列表的空目录。有些目录中包含目录。

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

我该如何测试?

例如:

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

2
我认为马丁的答案在这里是最合适的。当前接受的答案只是一个不完整的伪代码。
莱奥列奥波尔德·赫兹준 영

Answers:


34

检查是否find <dir> -type f输出任何东西。这是一个例子:

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

2
不,它不会输出子目录。那-type f是为了什么。
Marcelo Cantos 2010年

但是,如果有空文件,您的解决方案将不会产生此消息。
Yasir Arsanukaev 2010年

3
Yasir:我认为包含空文件的目录本身不是空的。那不是正确的结果吗?
Ukko,2010年

2
@akostadinov:如果我按照OP的指示创建目录和文件mkdir A B C A/A1 A/A2 B/B1 C/C1 C/C2; touch A/A1/file1-并在我的答案中运行代码,它将报告OP要求的B和C为空。因此,您将需要比“它不起作用”更加具体。
Marcelo Cantos 2013年

1
如果您是像我这样的Bash新手,请检查-z 在这里的含义。
OmarOthman '17

255

这取决于您要对空目录执行的操作。当我希望删除树中所有空目录(例如test目录)时,请使用以下命令。

find test -depth -empty -delete

关于上述命令,需要注意的一件事是,它还将删除空文件,因此请使用-type d选项来避免这种情况。

find test -depth -type d -empty -delete

拖放-delete以查看匹配的文件和目录。

如果您对空目录树的定义是不包含任何文件,则您可以根据是否find test -type f返回任何内容将某些内容组合在一起。

find 是一个非常有用的工具,RTFM经常并且经常真正地了解它可以做什么:-)


8
-delete暗示-depth(至少对于GNU findutils 4.4.2)
Person Person II博士

4
不知道-empty,太方便了!
拉菲2015年

2
但是在不是最新,最好的linux的机器上。(EG Solaris),那么您就找不到像-empty或-delete这样的功能。
安东尼

3
在MacOS-X上,对于几乎空的目录,find test -name ".DS_Store" -delete请先运行,然后运行-empty delete命令。另请注意,就像到pushd父目录一样,因此find test变为find .,但是其余命令相同。
奥利

1
@Martin能否在-depth这里添加定义,即 查找原因以执行深度优先遍历,即以后顺序访问目录,并且目录中的所有条目将在目录本身之前起作用。我认为这是相关的。
莱奥列奥波尔德·赫兹준 영

48

您可以使用以下命令:

find . -type d -empty

1
-empty仅在当前目录完全为空时才起作用,而在子树中不包含文件时则不起作用。
Marcelo Cantos 2010年

@soField经过测试的find。FreeBSD和CentOS使用-d型-empty。工作良好。您的操作系统是什么?
mosg,2010年

1
hp-ux,因此没有空参数
soField 2010年

@soField因此,您发现,对我们所有人来说,最好将此数据发布到您的问题的顶部……
mosg 2010年

2
find在solaris上也不具有-empty,但是它具有-depth来强制进行深度优先遍历,因此可以在检查父目录的空度之前删除空的子目录。
eirikma 2011年

26
find directory -mindepth 1 -type d -empty -delete

这是我发现最有趣的版本。如果从内部目录执行,它将删除下面的所有空目录(如果目录仅包含空目录,则该目录被视为空目录)。

mindepth选项可防止在目录为空时删除目录本身。


2
您也可以跟着rmdir --ignore-fail-on-non-empty -p directory摆脱父母。
皮特·彼得森

@Pete Peterson我的命令似乎删除仅包含其他空目录的目录(这也是OP似乎想要的)。我注意到,您的命令通常会将用户留在缺少i节点的目录中,即使他们完成了所需的操作,这也可能使他们感到困惑。也许我错过了重点。
Person Person II博士2015年

23

find . -type d -empty

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

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

在目录上不执行任何操作。它们只是列出。这对我有用。


16

只是找到空的目录

为了只找到空目录(如问题标题中所指定),mosg的答案是正确的:

find -type d -empty

但是-empty在非常老的find版本上可能不可用(例如,HP-UX就是这种情况)。如果是这种情况,请参阅以下部分中描述的技术。目录是否为空?

删除空目录

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

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 {} `;`

目录是空的吗?

这些答案大多数都解释了如何检查目录是否为空。因此,我在这里提供了我所知道的三种不同的技术:

  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类似于少find -maxdepth 0使用字符
    • find -type d 仅打印目录
    • find -empty 打印空目录和文件

      > 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} ))

    这个技巧是100%,bash但是会调用(产生)一个子shell。这个想法来自Bruno De Fraine,并根据teambob的评论进行了改进。我建议如果您使用 并且您的脚本不必是可移植的。

    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) ]

    此技巧的灵感来自nixCraft在2007年发布的文章安德鲁·泰勒(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

    或单行Bashism版本:

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

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


rmdir -vp因为我不仅需要删除根目录下的所有空目录,还需要删除文件后检查空目录和父目录,因此对我有很大帮助。在我的情况下,只要我不在要从中删除文件的树中,空目录就可以了。谢谢!
Ethan Hohensee

2

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

# 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 /
    | |-目录/
    | `-file4
    `-dir5 /
        `-dirE /
            `-dir_V /

运行该函数的结果将是:

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

错过了/dir4/dirD。如果移动递归调用findempty "$dir"fi,功能将包括其结果目录。


2

怎么rmdir *样 该命令将在非空目录上失败。


我有时会做一些一般清理工作。还完成了类似的操作, rmdir */*/* */* * 尽管该操作无法处理“点文件”,但是在手动情况下(清理数据文件),通常不会使用“点文件”。但是,递归方法是用于更自动化的常规清理,尤其是在非常大的目录结构中。
安东尼

在一种情况下,情况更加复杂,因为我需要删除空目录,其中“空”包括可能包含单个“自述”文件的目录。目录中的其他任何内容都不是“空”的。在该示例中,目录结构涉及成千上万的子目录。
安东尼


0

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

test/
test/test2/
test/test2/test2.2/
test/test3/
test/test3/file

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

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


运会要求测试/ test2将被也恢复

确实。但是我认为他可以阅读“查找手册”页面以进行进一步的介绍。根据结果​​调整深度的脚本可以正常工作。
詹姆斯·萨姆纳斯

这是供mye使用的最有用的版本,谢谢
Andreas

0

一个简单的方法是

$ [ "$(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"

0
find . -name -type d -ls |awk '($2==0){print $11}'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.