查找空目录

问题描述 投票:0回答:12

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

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

我该如何测试这个?

例如:

A>A1(file1),A2 this is not empty beacuse of file1
B>B1(no file) this is empty
C>C1,C2 this is empty
bash unix directory
12个回答
315
投票

以下命令将删除所有空目录(没有子目录的目录)。由于它是深度优先(自下而上)的,因此它将删除仅包含(空)目录作为子目录的目录。请注意,在

find
中,参数的顺序很重要。

find test -depth -type d -empty -delete

拖放

-delete
以查看匹配的文件和目录,但请注意,由于
-depth
,将不会列出将 空的父目录。如果您想
删除空文件,请删除-type d

例如:

$ mkdir -p test/foo/bar/baz; touch test/foo/afile.txt

$ find test -printf '%y %p\n'
d test
d test/foo
d test/foo/bar
d test/foo/bar/baz
f test/foo/afile.txt

$ find test -depth -type d -empty -delete

$ find test -printf '%y %p\n'
d test
d test/foo
f test/foo/afile.txt

81
投票

您可以使用以下命令:

find . -type d -empty

35
投票

检查

find <dir> -type f
是否输出任何内容。这是一个例子:

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

28
投票
find directory -mindepth 1 -type d -empty -delete

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

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


24
投票

find . -type d -empty

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

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

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


18
投票

只要找到空目录

为了找到空目录(如问题标题中指定),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
    。但文件和空目录没有区别。


3
投票

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


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
}

给出此示例目录结构:

 。
    |-- 目录1/
    |-- 目录2/
    | `--dirB/
    |-- dir3/
    | `--dirC/
    | `-- 文件5
    |-- dir4/
    | |-- dirD/
    | `-- 文件4
    `--dir5/
        `--dirE/
            `--dir_V/

运行该函数的结果将是:

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

错过了

/dir4/dirD
。如果将递归调用
findempty "$dir"
移到
fi
之后,该函数将在其结果中包含该目录。


1
投票

如果目录为空(或不存在),则以下命令返回 1,否则返回 0(因此可以在 shell 脚本中使用

!
反转返回码):

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

0
投票

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

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

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

发出

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


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}'
© www.soinside.com 2019 - 2024. All rights reserved.