【问题标题】:Finding directories that contains given files?查找包含给定文件的目录?
【发布时间】:2025-12-05 15:35:01
【问题描述】:

我希望这是一个有趣的问题..我想找到一个包含所有给定文件的目录..到目前为止我所做的如下

在 unix 中查找多个文件...

find . -type f \( -name "*cache" -o -name "*xml" -o -name "*html" \)

参考:http://alvinalexander.com/linux-unix/linux-find-multiple-filenames-patterns-command-example

仅查找包含给定文件的目录...

find . -type f -name '*.pdf' |sed 's#\(.*\)/.*#\1#' |sort -u

参考:http://www.unix.com/unix-for-dummies-questions-and-answers/107488-find-files-display-only-directory-list-containing-those-files.html

如何创建一个命令,该命令将为我提供一个包含所有给定文件的目录...(文件必须在给定目录中,而不是在子目录中......并且列表中给出的所有文件都必须存在)

想搜索WordPress主题目录

【问题讨论】:

  • 您要查找的文件列表在哪里?
  • index.php style.css page.php single.php comment.php wordpress 主题所需的基本文件。我的目标是找到给定 linux 系统中存在的所有 wordpress 主题。

标签: bash shell unix find command


【解决方案1】:

你可以像这样使用find

find -type d -exec sh -c '[ -f "$0"/index.php ] && [ -f "$0"/style.css ]' '{}' \; -print

要搜索更多文件,只需像&& [ -f "$0"/other_file ] 一样添加它们。 sh 的返回码将指示是否可以找到所有文件。只有当sh 成功退出时,即当所有文件都已找到时,才会打印目录名称。

测试一下:

$ mkdir dir1
$ touch dir1/a
$ mkdir dir2
$ touch dir2/a
$ touch dir2/b
$ find -type d -exec sh -c '[ -f "$0"/a ] && [ -f "$0"/b ]' '{}' \; -print
./dir2

在这里我创建了两个目录,dir1dir2dir2 包含这两个文件,因此会打印其名称。

正如 gniourf_gniourf 在 cmets 中提到的(谢谢),没有必要使用sh 来执行此操作。相反,您可以这样做:

find -type d -exec test -f '{}'/a -a -f '{}'/b \; -print

[test 做同样的事情。这种方法使用-a 而不是&& 来组合多个单独的测试,从而减少了正在执行的进程数。

响应您的评论,您可以将找到的所有目录添加到存档中,如下所示:

find -type d -exec test -f '{}'/a -a -f '{}'/b \; -print0 | tar --null -T - -cf archive.tar.bz2

-print0 选项打印每个目录的名称,以空字节分隔。这很有用,因为它可以防止名称中包含空格的文件出现问题。名称由tar 读取并添加到 bzip 压缩存档中。请注意,find 的某些版本不支持-print0 选项。如果您的版本不支持它,您可以使用-print(并将--null 选项删除到tar),具体取决于您的目录名称。

【讨论】:

  • 如何压缩我们得到的所有目录作为上述命令的输出???我的意思是一次将所有目录添加到存档中...
  • 无法解压存档,出现类似 archive.tar.bz2 的错误看起来不像 tar 文件。
    bzip2 -cd archive.tar.bz2 | tar xvf -
    bzip2 -d archive.tar.bz2
    tar xvjf archive.tar.bz2
    tar jfx archive.tar.bz2 以及如何通过 PHP exec() 函数运行命令??我需要将目录存储在 PHP 的数组中。提前谢谢你:)
  • @vivek 我的回答中的命令已经创建了一个 bzip 压缩的存档。要解压它,您可以使用tar -jxf archive.tar.bz2。如果您还有其他问题,我认为您应该单独提问,因为这个问题可能会变得过于广泛。
【解决方案2】:

你可以使用这个脚本:

#!/bin/bash

# list of files to be found
arr=(index.php style.css page.php single.php comment.php)
# length of the array
len="${#arr[@]}"

# cd to top level themes directory
cd themes

# search for listed files in all the subdirectories from current path
while IFS= read -d '' -r dir; do
   [[ $(ls "${arr[@]/#/$dir/}" 2>/dev/null | wc -l) -eq $len ]] && echo "$dir"
done < <(find . -type d -print0)

【讨论】:

  • 它工作正常并提供预期的输出。谢谢你的时间先生。当我通过命令行运行它时它工作正常,但它给出了错误,例如“第 11 行的意外标记 `
  • 两个答案都是正确的,但我无法接受。它只是在它们之间不断切换。
  • 是的,您不能将两个答案都标记为已接受。只有最适合您的一项才会被标记。
  • 你能解释一下脚本吗?