私のリストにあるすべてのファイルを含むディレクトリを探します。

私のリストにあるすべてのファイルを含むディレクトリを探します。

同じ親ディレクトリにある他の4つのファイルを参照するファイルを移動しました。今、私のビルド環境に同じ名前のファイルがたくさんあるので、どの親ディレクトリが何であるかを調べようとしています。しかし、私は間違ったファイルをコピーする危険を冒したくありません。だから私はLinux findコマンドや他のコマンドに2つ以上の文字列と一致する結果を与えるように指示する方法があるかどうか疑問に思います。それで、ファイルが含まれている場所と一致するものを見たいと思います。

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

1 つの方法は、ファイル名の 1 つを見つけて(わかっている場合は最もまれな名前を選択して)、一致する項目をフィルタリングして他のファイルが存在するファイル名のみを保持することです。

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

アクションを使用するには、findシェルフラグメントの戻りコードを使用できますが、これはディレクトリではなく最初のファイルに適用されます。たとえば、次のコードスニペットはフォームの出力を印刷します./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

別の方法は、名前のリストを生成してフィルタリングすることです。これはやや面倒で効率が悪くなりますが、ファイル名のインデックスがあればから切り替えることができるという利点がありますfindlocateファイル名に改行文字が含まれていないとします。

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

私はこれらすべてを一人で行うことができるどんな検索オプションも知りません。 grepを使用すると、これを達成できます。検索するすべてのファイル名を、次のパターンを使用して /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

non-common_directoryにもfoo、bar、bazがあります。

この9 mcコマンドは、出力を調整するためのp9pのマルチカラムフォーマッタです。

関連情報