假设我有一个文件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之后和文件名之前的空格