如何删除其中包含 n 个或更少文件的文件夹?

如何删除其中包含 n 个或更少文件的文件夹?

我需要清理一些文件夹,我想删除包含 10 个或更少文件的目录。我尝试查看 GNU 的find,但没有任何与目录中的文件数量相关的内容。我应该使用什么命令来实现这一点?

答案1

一种方法是使用find-exec操作来执行文件数量的自定义测试。

可以使用第二个find命令来wc查找和计算每个目录中的文件数量,但更好的选择可能是使用 shell 通配符将文件名放入数组中,然后返回一个逻辑值,指示数组的大小是否小于阈值,即

files=( dir/* ); ((${#files[@]} < 10))

综合起来,我们应该能够列表所有包含少于 10 个文件的子目录(包括子子目录),使用

find . -depth -type d ! -name '.' -exec bash -c '
  shopt -s nullglob; files=( "$1"/* ); ((${#files[@]} < ${2:-10}))
  ' bash {} 10 \; -print0 | xargs -0

(您可以调整不同阈值10后的数字-如果没有给出第二个参数,参数扩展会将其默认为 10 个文件)。例如,给定bash {}${2:-10}

$ tree .
.
├── bar
│   ├── file1
│   ├── file2
│   ├── file3
│   ├── file4
│   ├── file5
│   ├── file6
│   ├── file7
│   ├── file8
│   ├── file9
│   └── other file
├── baz
│   ├── other file
│   └── subdir
└── foo
    └── somefile

4 directories, 12 files

然后

find . -depth -type d ! -name '.' -exec bash -c '
  shopt -s nullglob; files=( "$1"/* ); ((${#files[@]} < "${2:-10}"))
  ' bash {} 10 \; -print0 | xargs -0
./foo ./baz/subdir ./baz

如果这样做似乎是正确的,你实际上可以通过添加来删除它们rm -rf 但请一定要小心谨慎 - 记住没有“撤消”

find . -depth -type d ! -name '.' -exec bash -c '
  shopt -s nullglob; files=( "$1"/* ); ((${#files[@]} < ${2:-10}))
' bash {} 10 \; -print0 | xargs -0 rm -rf

xargs可以通过使用另一个-exec操作更直接地运行来消除rm,但上面的公式可以很容易地概括 - 打印,统计,删除或其他。)

注意,这将以递归方式执行,即最初包含多个n文件的目录包括子目录可能会因为某些子目录本身作为find目录树的备份被删除而被删除 - 当前目录受到明确保护,不会因测试而被删除! -name '.'

如果你需要它以递归方式执行,您可以简单地循环遍历目录并执行相同的文件计数和测试逻辑,例如删除当前目录中包含少于 10 个文件的所有一级目录

shopt -s nullglob
for d in */; do
  files=( "$d"/* )
  ((${#files[@]} < 10)) && echo rm -rf -- "$d"
done 

答案2

我没有完全测试过,但它应该可以工作。您也可以使用它find来实现这一点。

# Loop over all files
for dir in * **/*; do
    # Make sure this is a directory
    if [ -d "${dir}" ]; then
        # Get the number of files (not including directories) in this directory
        FILE_COUNT=`ls $dir -1 | grep -v / | wc -l`
        # Check if it's less than 10
        if [ $FILE_COUNT -lt 10 ]; then
            # Delete the directory
            rm -rf "${dir}"
        fi
    fi
done

相关内容