web-dev-qa-db-ja.com

awk内でgrepを実行する方法は?

いくつかの列といくつかの行を含むファイル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が機能しない理由も示しています。パラメーターは最後の引数ではありません

8
e271p314

フォローしてみてください

awk '{print $1}' input.txt | xargs -n 1 -I pattern grep -rn pattern dir
6
jkshah

grepawkは不要で、ファイルを開くために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ディレクトリ内のすべてのファイルでその配列から各キーを探すだけです。

27
Ed Morton

あなたが最初にすべきことは、研究 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
4
ghoti

プロセス置換を使用して、-fオプションを介してgrepに渡すことができるキーワード「ファイル」を作成します。

grep -f <(awk '{print $1}' input.txt) dir/*

これにより、dirの各ファイルで、awkコマンドによって出力されたキーワードを含む行が検索されます。それは同等です

awk '{print $1}' input.txt > tmp.txt
grep -f tmp.txt dir/*
2
chepner

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
1
ArturFH

それでもawk内でgrepを使用する場合は、$ 1、$ 2などが引用符の外にあることを確認してください。例えば。これは完璧に機能します

cat file_having_query | awk '{system("grep " $1 " file_to_be_greped")}'

// grepの後、ファイル名の前のスペースに注意してください

1
Mohit Verma