查找包含给定文件的目录?

6
我希望这是一个有趣的问题..我想找到一个包含所有给定文件的目录..直到现在我的做法如下
在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 主题目录。

你在找的文件列表在哪里? - anubhava
index.php style.css page.php single.php comment.php是WordPress主题所需的基本文件。我的目标是在给定的Linux系统中找到所有存在的WordPress主题。 - VIVEK SEDANI
2个回答

6
您可以这样使用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

我创建了两个目录,dir1dir2。因为dir2包含了两个文件,所以它的名称被打印出来。

正如gnioruf_gniourf在评论中提到的(谢谢),使用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 选项会将每个目录的名称以 null 字节分隔打印出来。这非常有用,因为它可以防止文件名中包含空格时出现问题。 tar 会读取这些名称并将其添加到 bzip 压缩的归档文件中。请注意,某些版本的 find 不支持 -print0 选项。如果您的版本不支持该选项,则可能需要使用 -print(并删除 --null 选项),具体取决于您的目录名称。

如何压缩上述命令的所有目录?我的意思是一次将所有目录添加到归档中... - VIVEK SEDANI
无法解压缩归档文件,出现错误,例如archive.tar.bz2不像是一个tar文件。 <br/> bzip2 -cd archive.tar.bz2 | tar xvf - <br/> bzip2 -d archive.tar.bz2 <br/> tar xvjf archive.tar.bz2 <br/> tar jfx archive.tar.bz2 并且如何通过PHP exec()函数运行命令? 我需要在PHP中将目录存储在数组中。谢谢您的帮助 :) - VIVEK SEDANI
@vivek 我的回答中的命令已经创建了一个bzip压缩的归档文件。要解压缩它,您可以使用 tar -jxf archive.tar.bz2 命令。如果您有任何进一步的问题,我认为您应该单独提出它们,因为这个问题可能会变得太广泛。 - Tom Fenech

1
你可以使用这个脚本:

#!/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行附近出现了“语法错误,意外的标记`<'”的错误。其他一切都很好。谢谢您先生... - VIVEK SEDANI
这两个答案都是正确的,但我无法接受它们。它只是在它们之间切换。 - VIVEK SEDANI
是的,您不能将两个答案都标记为已接受。只有最适合您的那个答案会被标记。 - anubhava
你能解释一下这个脚本吗? - Seabass77

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接