如何查找仅包含特定文件的目录

Ram*_*hom 8 find

我有几个包含无用文件的目录(如*.tmp, desktop.ini, Thumbs.db, .picasa.ini)。

如何扫描所有驱动器以查找仅包含其中一些文件的目录?

Kus*_*nda 9

为了找到不包含其他名称的所有目录比*.tmpdesktop.iniThumbs.db,和/或.picasa.ini

find . -type d -exec bash -O dotglob -c '
    for dirpath do
        ok=true
        seen_files=false
        set -- "$dirpath"/*
        for name do
            [ -d "$name" ] && continue  # skip dirs
            seen_files=true
            case "${name##*/}" in
                *.tmp|desktop.ini|Thumbs.db|.picasa.ini) ;; # do nothing
                *) ok=false; break
            esac
        done

        "$seen_files" && "$ok" && printf "%s\n" "$dirpath"
    done' bash {} +
Run Code Online (Sandbox Code Playgroud)

这将用于find定位当前目录(包括当前目录)下的任何目录并将它们传递给 shell 脚本。

shell 脚本遍历给定的目录路径,并在每个目录路径中进行扩展*dotglob设置 shell 选项bash以捕获隐藏名称)。

然后它遍历结果名称列表,并将它们与我们想要查找的特定模式和名称(忽略目录)进行匹配。如果它发现与我们的列表不匹配的任何其他名称,它将设置okfalse(从曾经true)并跳出该内部循环。

一旦我们看到除目录(或指向目录的符号链接)以外的任何类型的文件,该seen_files变量就会变为。此变量帮助我们避免报告仅包含其他子目录的子目录。true

然后运行$seen_filesand $ok(truefalse) 并且如果它们都是true,这意味着目录至少包含一个常规文件,并且只包含我们列表中的文件名,它会打印目录的路径名。

代替

set -- "$dirpath"/*
for name do
Run Code Online (Sandbox Code Playgroud)

你显然可以做到

for name in "$dirpath"/*; do
Run Code Online (Sandbox Code Playgroud)

反而。

测试:

find . -type d -exec bash -O dotglob -c '
    for dirpath do
        ok=true
        seen_files=false
        set -- "$dirpath"/*
        for name do
            [ -d "$name" ] && continue  # skip dirs
            seen_files=true
            case "${name##*/}" in
                *.tmp|desktop.ini|Thumbs.db|.picasa.ini) ;; # do nothing
                *) ok=false; break
            esac
        done

        "$seen_files" && "$ok" && printf "%s\n" "$dirpath"
    done' bash {} +
Run Code Online (Sandbox Code Playgroud)

find命令在此处运行,产生输出...)

./dir
Run Code Online (Sandbox Code Playgroud)

这意味着该目录./dir仅包含列表中的名称(忽略目录),同时还./dir/dir包含其他内容。

如果您[ -d "$name" ] && continue从代码中删除,./dir将不会找到该目录,因为它包含dir不在我们列表中的名称 ( )。

  • 但它们*只包含其中一些文件*。好吧,要求有点模棱两可,我想你的解释比我的更有意义。我已经用这两个选项更新了我的答案。 (2认同)

Ned*_*d64 3

您需要指定文件或文件夹,最好按名称指定,例如:

find ${HOME} -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty rm
Run Code Online (Sandbox Code Playgroud)

将找到所有-type f名为 ( ) -iname“thumbs.db”的文件 ( )(由于iin忽略大小写iname),然后删除 ( rm) 它们。

您可以使用文件名模式,例如

find ${HOME} -type f -iname '*.tmp' -print0 | xargs -0 --no-run-if-empty rm
Run Code Online (Sandbox Code Playgroud)

警告:请小心您输入的内容,可能会在没有询问您的情况下进行删除。

请定期进行备份 - 在开始清理工作之前可能是一个好时机!

如果您想了解会发生什么,请在rm执行任何操作之前先查看文件列表,例如:

find ${HOME} -type f -iname thumbs.db -print0 | xargs -0 --no-run-if-empty ls -l
Run Code Online (Sandbox Code Playgroud)