grep -f MY_FILE
コマンドラインで直接指定するのではなく、ファイルから取得したパターンを検索するために使用できるオプションがあります。
find
コマンドで同様のことを実行し、入力ファイルから検索するパターンを読み取らせるオプションはありますか?
答え1
find
にはそのような機能が組み込まれていないようですが、次のようにファイルからの引数を使用してxargs
複数のコマンドを構築するために使用できます。find
xargs -a patterns.txt -I% find Pictures/ -name %
patterns.txt
フィルターに適したパターンのリストは、-name
1 行につき 1 つのパターンです。先頭/末尾にスペースがないことに注意してください。スペースはパターンに含まれます。例:
*.jpg
2018-06-*
*foo*
unicorn.png
注記:この答えは非常に簡単でエレガントに見えますが、コメントでいくつかの欠点があることが正しく指摘されています。
find
ファイル内のパターンごとに 1 回 実行され、検索フォルダー全体を繰り返しスキャンすることになるため、フォルダーが大きい場合やパターンが多い場合はパフォーマンスがあまり良くありません。そのため、重複する可能性のあるパターンが複数ある場合 ( や
*.jpg
など*foo*
)、複数のパターンに一致するファイルは結果にその回数だけ表示されます。とにかく名前のみを印刷する場合は、出力をパイプしてsort -u
重複を削除できますが、たとえばそれらの結果を削除したり、それらに対してコマンドを実行したりする場合は-exec
、これがより望ましくない場合があります。これらの欠点のいずれかが使用事例で問題になる場合は、代替の回答のいずれかを選択する方がよいでしょう。
コマンドの説明:
xargs
引数のリストを読み取り、それを使用して新しいコマンドラインを構築して実行します。-a patterns.txt
標準入力ではなくそのファイルから読み取るように指示します。-I%
読み取った引数を単にコマンド ラインの末尾に追加するのではなく、%
指定したコマンド ラインの文字を 1 つの引数に置き換えるように指示します。これは、入力引数ごとに 1 つの個別のコマンドを作成して実行することを意味します。find Pictures/ -name %
は、 を置き換えて引数を挿入するコマンド ラインです。は、挿入される各引数が単一のトークンとして扱われ、それ自体が分割されないようにするため、%
ここでは引用符で囲む必要はありません。 もちろん、 を独自の検索ディレクトリに置き換えたり、 以外の異なる や などのフィルターを使用したりすることもできます。挿入オプションを使用しているため、コマンドの末尾になどのアクションを追加することもできます。xargs
Pictures/
-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
コマンドに渡されます。