同じ親ディレクトリにある他の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
別の方法は、名前のリストを生成してフィルタリングすることです。これはやや面倒で効率が悪くなりますが、ファイル名のインデックスがあればから切り替えることができるという利点があります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
私はこれらすべてを一人で行うことができるどんな検索オプションも知りません。 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のマルチカラムフォーマッタです。