find コマンドを使用してファイルから複数のパターンを検索する

find コマンドを使用してファイルから複数のパターンを検索する

grep -f MY_FILEコマンドラインで直接指定するのではなく、ファイルから取得したパターンを検索するために使用できるオプションがあります。

findコマンドで同様のことを実行し、入力ファイルから検索するパターンを読み取らせるオプションはありますか?

答え1

findにはそのような機能が組み込まれていないようですが、次のようにファイルからの引数を使用してxargs複数のコマンドを構築するために使用できます。find

xargs -a patterns.txt -I% find Pictures/ -name %

patterns.txtフィルターに適したパターンのリストは、-name1 行につき 1 つのパターンです。先頭/末尾にスペースがないことに注意してください。スペースはパターンに含まれます。例:

*.jpg
2018-06-*
*foo*
unicorn.png

注記:この答えは非常に簡単でエレガントに見えますが、コメントでいくつかの欠点があることが正しく指摘されています。

findファイル内のパターンごとに 1 回 実行され、検索フォルダー全体を繰り返しスキャンすることになるため、フォルダーが大きい場合やパターンが多い場合はパフォーマンスがあまり良くありません。

そのため、重複する可能性のあるパターンが複数ある場合 ( や*.jpgなど*foo*)、複数のパターンに一致するファイルは結果にその回数だけ表示されます。とにかく名前のみを印刷する場合は、出力をパイプしてsort -u重複を削除できますが、たとえばそれらの結果を削除したり、それらに対してコマンドを実行したりする場合は-exec、これがより望ましくない場合があります。

これらの欠点のいずれかが使用事例で問題になる場合は、代替の回答のいずれかを選択する方がよいでしょう。

コマンドの説明:

  • xargs引数のリストを読み取り、それを使用して新しいコマンドラインを構築して実行します。
  • -a patterns.txt標準入力ではなくそのファイルから読み取るように指示します。
  • -I%読み取った引数を単にコマンド ラインの末尾に追加するのではなく、%指定したコマンド ラインの文字を 1 つの引数に置き換えるように指示します。これは、入力引数ごとに 1 つの個別のコマンドを作成して実行することを意味します。
  • find Pictures/ -name %は、 を置き換えて引数を挿入するコマンド ラインです。は、挿入される各引数が単一のトークンとして扱われ、それ自体が分割されないようにするため、%ここでは引用符で囲む必要はありません。 もちろん、 を独自の検索ディレクトリに置き換えたり、 以外の異なる や などのフィルターを使用したりすることもできます。挿入オプションを使用しているため、コマンドの末尾になどのアクションを追加することもできます。xargsPictures/-name-exec ...

答え2

を使用すると、ファイルの内容から正規表現を簡単に作成できますpaste -sd'|' bar

find ~/foo -regextype egrep -regex "^.*/($(paste -sd'|' bar))$"

正規表現は"^.*/(a|b)$"

答え3

つい最近、私は答え-regexフラグを使用して複数のパターンを組み合わせますfind。これに基づいて、同じジョブを実行する小さなスクリプトまたは関数を作成し、ファイルからパターンのリストを構築することができます。

#!/bin/bash

read_file(){
    local full_pattern=""
    while IFS= read -r pattern; do
        if [ -z "$full_pattern"  ];then
            full_pattern="$pattern"
            continue
        fi
        full_pattern="$full_pattern\|$pattern"
    done < "$1"
    echo "$full_pattern"
}

fp=$(read_file "$1" )
find "$2" -type f -regex ".*\($fp\).*$" 

これが何をするか:

  • スクリプトを として呼び出しますfindf.sh input.txt /etc。最初の位置パラメータはパターンを含むファイル、2 番目は検索するディレクトリです。GNU find は、.ディレクトリ引数が省略された場合はディレクトリであると想定するため、 は$2必須ではありません。
  • この関数はread_file、スクリプトの最初の位置パラメータである入力ファイルを読み取ります。これにより、フラグのパターンが構築されます-regex
  • このパターンはスクリプトの「メイン」ブロックにエコーバックされ、fp変数に保存され、findコマンドに渡されます。

関連情報