Linux 如何在awk中运行grep?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20080098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to run grep inside awk?
提问by e271p314
Suppose I have a file input.txt
with few columns and few rows, the first column is the key, and a directory dir
with files which contain some of these keys. I want to find all lines in the files in dir
which contain these key words. At first I tried to run the command
假设我有一个input.txt
包含几列和几行的文件,第一列是键,以及一个dir
包含其中一些键的文件的目录。我想在dir
包含这些关键字的文件中找到所有行。起初我试图运行命令
cat input.txt | awk '{print }' | xargs grep dir
This doesn't work because it thinks the keys are paths on my file system. Next I tried something like
这不起作用,因为它认为密钥是我文件系统上的路径。接下来我尝试了类似的东西
cat input.txt | awk '{system("grep -rn dir ")}'
But this didn't work either, eventually I have to admit that even this doesn't work
但这也行不通,最终我不得不承认,即使这样也行不通
cat input.txt | awk '{system("echo ")}'
After I tried to use \
to escape the white space and the $
sign, I came here to ask for your advice, any ideas?
在我尝试使用\
逃避空白和$
标志之后,我来到这里征求您的意见,有什么想法吗?
Of course I can do something like
当然我可以做类似的事情
for x in `cat input.txt` ; do grep -rn $x dir ; done
This is not good enough, because it takes two commands, but I want only one. This also shows why xargs
doesn't work, the parameter is not the last argument
这还不够好,因为它需要两个命令,但我只想要一个。这也说明了为什么xargs
不起作用,参数不是最后一个参数
采纳答案by jkshah
Try following
尝试以下
awk '{print }' input.txt | xargs -n 1 -I pattern grep -rn pattern dir
回答by chepner
Use process substitution to create a keyword "file" that you can pass to grep
via the -f
option:
使用进程替换创建一个关键字“文件”,您可以通过选项传递给grep
它-f
:
grep -f <(awk '{print }' input.txt) dir/*
This will search each file in dir
for lines containing keywords printed by the awk
command. It's equivalent to
这将在每个文件中搜索dir
包含awk
命令打印的关键字的行。它相当于
awk '{print }' input.txt > tmp.txt
grep -f tmp.txt dir/*
回答by ghoti
First thing you should do is research this.
你应该做的第一件事就是研究这个。
Next ... you don't need to grep inside awk. That's completely redundant. It's like ... stuffing your turkey with .. a turkey.
接下来……您不需要在 awk 中使用 grep。那完全是多余的。这就像......用......火鸡填充你的火鸡。
Awk can process input and do "grep" like things itself, without the need to launch the grep command. But you don't even need to do this. Adapting your first example:
awk 可以处理输入并像事情本身一样执行“grep”,而无需启动 grep 命令。但你甚至不需要这样做。调整你的第一个例子:
awk '{print }' input.txt | xargs -n 1 -I % grep % dir
This uses xargs' -I
option to put xargs' input into a different place on the command line it runs. In FreeBSD or OSX, you would use a -J
option instead.
这使用 xargs 的-I
选项将 xargs 的输入放在它运行的命令行上的不同位置。在 FreeBSD 或 OSX 中,您可以使用-J
选项来代替。
But I prefer your for loop idea, converted into a while loop:
但我更喜欢你的 for 循环想法,转换成一个 while 循环:
while read key junk; do grep -rn "$key" dir ; done < input.txt
回答by Ed Morton
You don't need grep
with awk
, and you don't need cat
to open files:
您不需要grep
with awk
,也不需要cat
打开文件:
awk 'NR==FNR{keys[]; next} {for (key in keys) if (real_input_generating_command |
awk 'NR==FNR{keys[]; next} {for (key in keys) if (arturcz@szczaw:/tmp/s$ cat words.txt
foo
bar
fubar
foobaz
arturcz@szczaw:/tmp/s$ grep 'foo\|baz' words.txt
foo
foobaz
~ key) {print FILENAME, grep `commands|to|prepare|a|keywords|list` directory
; next} }' - dir/*
~ key) {print FILENAME, cat file_having_query | awk '{system("grep " " file_to_be_greped")}'
; next} }' input.txt dir/*
Nor do you need xargs, or shell loops or anything else - just one simple awk command does it all.
您也不需要 xargs、shell 循环或其他任何东西 - 只需一个简单的 awk 命令即可完成所有工作。
If input.txt is not a file, then tweak the above to:
如果 input.txt 不是文件,则将上述内容调整为:
##代码##All it's doing is creating an array of keys from the first file (or input stream) and then looking for each key from that array in every file in the dir directory.
它所做的只是从第一个文件(或输入流)创建一个键数组,然后在 dir 目录中的每个文件中查找该数组中的每个键。
回答by ArturFH
grep requires parameters in order: [what to search] [where to search]. You need to merge keys received from awk and pass them to grep using the \| regexp operator. For example:
grep 按顺序需要参数:[搜索内容] [搜索位置]。您需要合并从 awk 收到的密钥并使用 \| 将它们传递给 grep 正则表达式运算符。例如:
##代码##Finally, you will finish with:
最后,您将完成:
##代码##回答by Mohit Verma
In case you still want to use grep inside awk, make sure $1, $2 etc are outside quote. eg. this works perfectly
如果您仍想在 awk 中使用 grep,请确保 $1、$2 等不在报价中。例如。这完美地工作
##代码##// notice the space after grep and before file name
// 注意grep 之后和文件名之前的空格