如何在awk中运行grep?

时间:2013-11-19 19:14:27

标签: linux bash 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

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

6 个答案:

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