查找包含我的列表中所有文件的目录

查找包含我的列表中所有文件的目录

我移动了一个文件,该文件引用了具有相同父目录的其他四个文件。现在我正在尝试找出哪个父目录,因为我的构建环境中有许多同名的文件。但我不想冒险复制错误的文件。所以我想知道是否有办法告诉 Linux find 命令或其他命令给我匹配两个或多个字符串的结果。所以我只想查看包含文件的位置的匹配项:

foo & bar & buz

我总是可以将其输入到 grep 中以获取所需的公共目录,但如果有更简单的方法,那么我会喜欢它。就像是:

common_direcoty/foo & common_directory/bar & common_directory/buz 

换句话说,我正在寻找具有公共目录的这些文件的副本。我不是在寻找仅与名称匹配的文件。

这是命令的输出,它给了我我想要的结果:

sansari@ubuntu:~/WORKING_DIRECTORY$ find . -name io.h -exec sh -c '[ -e "${0%/*}/kernel.h" ] && [ -e "${0%/*}/init.h" ]' {} \; -print
./include/linux/io.h
sansari@ubuntu:~/WORKING_DIRECTORY/include/linux$ ls module.h
module.h
sansari@ubuntu:~/WORKING_DIRECTORY/include/linux$ ls kernel.h 
kernel.h
sansari@ubuntu:~/WORKING_DIRECTORY/include/linux$ ls init.h
init.h
sansari@ubuntu:~/WORKING_DIRECTORY/include/linux$ ls io.h
io.h

答案1

一种方法是查找其中一个文件名(如果您知道是哪一个,请选择最稀有的一个),然后过滤匹配项以仅保留其他文件存在的那些文件名。

find . -name foo -exec sh -c '[ -e "${0%/*}/bar" ] && [ -e "${0%/*}/buz" ] && echo "${0%/*}"' {} \;

如果您想使用某个find操作,则可以使用 shell 代码片段的返回代码,但这将应用于第一个文件,而不是目录。例如,以下代码片段打印表单的输出./path/to/foo

find . -name foo -exec sh -c '[ -e "${0%/*}/bar" ] && [ -e "${0%/*}/buz" ]' {} \; -print

如果您需要将名称作为参数传递:

find_multiple_files () {
  root=$1; shift
  name1=$2; shift
  find "$root" -name "$name1" -exec sh -c 'dir=${0%/*}; for x; do [ -e "$dir/$x" ] || exit 1; done; echo "$dir"' {} "$@" \;
}
find_multiple_files . foo bar buz

另一种方法是生成名称列表并过滤它们。这有点麻烦并且效率较低,但它的优点是如果您有文件名索引,则可以从 切换find到。locate我假设文件名不包含换行符。

locate foo |              # or: find -name foo
sed 's!/[^/]*$!!' |
xargs -I {} sh -c 'for x; do [ -e "$0/$x" ] || exit 1; done; echo "$0"' {} bar buz

答案2

我不知道有任何查找选项可以单独完成这一切。使用 greps 你可以实现这一点 - 将你想要查找的所有文件名放在一个单独的文件中,例如 /tmp/files_to_find,具有以下模式

在你的情况下 files_to_find 是

\/foo$
\/bar$
\/buz$

然后发出以下命令

find root_dir_to_search_in | grep -f /tmp/files_to_find | xargs -I{} dirname {} | sort | uniq -c | grep `wc -l /tmp/files_to_find | awk '{print $1}'`

答案3

您应该能够将find模式分组-or-and选择不同的模式。我不使用这样的选项,但它

$ find . \( -name foo -or -name bar -or -name buz \) -and -path '*/G/*'|9 mc
./G/buz ./G/bar ./G/foo

其中G= common_directory。我针对文件结构测试了这个

$ find . -name foo -or -name bar -or -name buz|9 mc
./G/buz ./G/bar ./G/foo ./F/buz ./F/bar ./F/foo

我在非 common_directory 中也有 foo、bar 和 baz。

9 mc命令是 p9p 的多列格式化程序,只是为了调整输出。

相关内容