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

7 delete files directory find

我需要进行一些文件夹清理,并且我想删除其中包含 10 个或更少文件的目录。我尝试查看 GNU 的find,但与目录中的文件数量无关。我应该使用什么命令来完成它?

ste*_*ver 3

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

\n\n

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

\n\n
files=( dir/* ); ((${#files[@]} < 10))\n
Run Code Online (Sandbox Code Playgroud)\n\n

把它们放在一起,我们应该能够列出所有少于 10 个文件的子目录(包括子子目录)

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

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

\n\n
$ tree .\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bar\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file1\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file2\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file3\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file4\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file5\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file6\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file7\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file8\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file9\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 other file\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 baz\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 other file\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 subdir\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 foo\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 somefile\n\n4 directories, 12 files\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后

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

如果这看起来是正确的,您实际上可以通过添加来删除它们,rm -rf 但请非常小心 - 请记住没有“撤消”

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

(可以通过使用另一个操作来运行来xargs消除-execrm来消除,但是上面的公式可以很容易地概括 - print、stat、remove 等等。)

\n\n

请注意,这将递归地起作用,即最初具有多个n文件(包括子目录)的目录可能会被删除,因为其中一些子目录本身在find备份目录树时被删除 - 当前目录被显式保护,以免被测试删除! -name \'.\'

\n\n

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

\n\n
shopt -s nullglob\nfor d in */; do\n  files=( "$d"/* )\n  ((${#files[@]} < 10)) && echo rm -rf -- "$d"\ndone \n
Run Code Online (Sandbox Code Playgroud)\n


小智 0

我没有完全测试这一点,但它应该有效。您也可以使用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
Run Code Online (Sandbox Code Playgroud)