いくつかの列といくつかの行を含むファイルinput.txt
があり、最初の列がキーであり、これらのキーのいくつかを含むファイルを含むディレクトリdir
があるとします。これらのキーワードを含むdir
内のファイル内のすべての行を検索したい。最初にコマンドを実行しようとしました
cat input.txt | awk '{print $1}' | xargs grep dir
キーは私のファイルシステム上のパスであると考えているため、これは機能しません。次に私は何かを試しました
cat input.txt | awk '{system("grep -rn dir $1")}'
しかし、これもうまくいきませんでした、結局私はこれでもうまくいかないことを認めなければなりません
cat input.txt | awk '{system("echo $1")}'
\
を使用して空白と$
記号を回避しようとした後、私はあなたのアドバイスやアイデアを求めるためにここに来ましたか?
もちろん、私は次のようなことができます
for x in `cat input.txt` ; do grep -rn $x dir ; done
2つのコマンドが必要なので、これでは十分ではありませんが、1つだけ必要です。これは、xargs
が機能しない理由も示しています。パラメーターは最後の引数ではありません
フォローしてみてください
awk '{print $1}' input.txt | xargs -n 1 -I pattern grep -rn pattern dir
grep
とawk
は不要で、ファイルを開くためにcat
は必要ありません。
awk 'NR==FNR{keys[$1]; next} {for (key in keys) if ($0 ~ key) {print FILENAME, $0; next} }' input.txt dir/*
また、xargsやシェルループなどは必要ありません。1つの単純なawkコマンドですべてが実行されます。
Input.txtがファイルでない場合は、上記を調整して次のようにします。
real_input_generating_command |
awk 'NR==FNR{keys[$1]; next} {for (key in keys) if ($0 ~ key) {print FILENAME, $0; next} }' - dir/*
最初のファイル(または入力ストリーム)からキーの配列を作成し、dirディレクトリ内のすべてのファイルでその配列から各キーを探すだけです。
あなたが最初にすべきことは、研究 this です。
次に... awk内でgrepする必要はありません。それは完全に冗長です。それは...七面鳥を七面鳥に詰め込むようなものです。
Awkは入力を処理し、grepコマンドを起動しなくても、それ自体のように「grep」を実行できます。しかし、これを行う必要すらありません。最初の例を採用する:
awk '{print $1}' input.txt | xargs -n 1 -I % grep % dir
これは、xargsの-I
オプションを使用して、xargsの入力を、それが実行するコマンドラインの別の場所に配置します。 FreeBSDまたはOSXでは、代わりに-J
オプションを使用します。
しかし、私はあなたのforループのアイデアを好み、whileループに変換します:
while read key junk; do grep -rn "$key" dir ; done < input.txt
プロセス置換を使用して、-f
オプションを介してgrep
に渡すことができるキーワード「ファイル」を作成します。
grep -f <(awk '{print $1}' input.txt) dir/*
これにより、dir
の各ファイルで、awk
コマンドによって出力されたキーワードを含む行が検索されます。それは同等です
awk '{print $1}' input.txt > tmp.txt
grep -f tmp.txt dir/*
grepには、[検索対象] [検索場所]の順にパラメーターが必要です。 awkから受け取ったキーをマージし、\ |を使用してそれらをgrepに渡す必要があります。正規表現演算子。例えば:
arturcz@szczaw:/tmp/s$ cat words.txt
foo
bar
fubar
foobaz
arturcz@szczaw:/tmp/s$ grep 'foo\|baz' words.txt
foo
foobaz
最後に、以下で終了します。
grep `commands|to|prepare|a|keywords|list` directory
それでもawk内でgrepを使用する場合は、$ 1、$ 2などが引用符の外にあることを確認してください。例えば。これは完璧に機能します
cat file_having_query | awk '{system("grep " $1 " file_to_be_greped")}'
// grepの後、ファイル名の前のスペースに注意してください