如何在awk中运行grep?

假设我有一个文件input.txt只有几列和几行,第一列是关键,目录dir与包含这些键的文件。 我想要find包含这些关键词的文件中的所有行。 起初我试图运行命令

 cat input.txt | awk '{print $1}' | xargs grep dir 

这不起作用,因为它认为键是我的文件系统上的path。 接下来我尝试了类似的东西

 cat input.txt | awk '{system("grep -rn dir $1")}' 

但是这也行不通,最后我不得不承认,即使这样也行不通

 cat input.txt | awk '{system("echo $1")}' 

在我试图用\逃离白色空间和$符号后,我来到这里请求你的build议,有什么想法?

当然,我可以做一些类似的事情

 for x in `cat input.txt` ; do grep -rn $x dir ; done 

这不够好,因为它需要两个命令,但我只需要一个。 这也说明了为什么xargs不工作,参数不是最后一个参数

尝试以下

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

你不需要awk grep ,你不需要cat来打开文件:

 awk 'NR==FNR{keys[$1]; next} {for (key in keys) if ($0 ~ key) {print FILENAME, $0; next} }' input.txt dir/* 

你也不需要xargs或者shell循环或者其他的东西 – 只需要一个简单的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目录中的每个文件中查找该数组中的每个键。

首先你要做的是研究这个 。

接下来…你不需要grep里面的awk。 这完全是多余的。 这就像…用火鸡塞火鸡。

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之后和文件名之前的空格