我移动了一个文件,该文件引用了具有相同父目录的其他四个文件。现在我正在尝试找出哪个父目录,因为我的构建环境中有许多同名的文件。但我不想冒险复制错误的文件。所以我想知道是否有办法告诉 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 的多列格式化程序,只是为了调整输出。