假设我有一个文件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
这还不够好,因为它需要两个命令,但我只想要一个。这也说明了为什么xargs
不起作用,参数不是最后一个参数
答案 0 :(得分:27)
您grep
不需要awk
,而且您不需要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目录中的每个文件中查找该数组中的每个键。
答案 1 :(得分:5)
尝试以下
awk '{print $1}' input.txt | xargs -n 1 -I pattern grep -rn pattern dir
答案 2 :(得分:4)
你应该做的第一件事就是研究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
答案 3 :(得分:2)
使用流程替换创建关键字“文件”,您可以通过grep
选项将其传递给-f
:
grep -f <(awk '{print $1}' input.txt) dir/*
这将在dir
中搜索包含awk
命令打印的关键字的行的每个文件。它相当于
awk '{print $1}' input.txt > tmp.txt
grep -f tmp.txt dir/*
答案 4 :(得分:1)
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
答案 5 :(得分:1)
如果您仍想在awk中使用grep,请确保$ 1,$ 2等在引号外。 例如。这完美地运作
CheckBox cb = (CheckBox)row.FindControl("ChkBox");
if (cb != null)
{
if (cb.Checked)
{
var OrderNoLabel = (Label)row.FindControl("OrderNo") ;
res = res + "" + OrderNoLabel.Text;// printing selected OrderNo
}
}
//注意grep之后和文件名之前的空格