21

有没有办法根据前一个 grep 的结果执行 grep,而不仅仅是将多个 grep 相互传递。例如,假设我有以下日志文​​件输出:

ID 1000 xyz occured
ID 1001 misc content
ID 1000 misc content
ID 1000 status code: 26348931276572174
ID 1000 misc content
ID 1001 misc content

首先,我想 grep 整个日志文件文件,看看是否存在“xyz 发生”。如果是,我想获取该事件的 ID 号,并通过 grep 遍历文件中具有该 ID 号的所有行来查找状态代码。

我想象我可以使用 xargs 或类似的东西,但我似乎无法让它工作。

grep "xyz occured" file.log | awk '{ print $2 }' | xargs grep "status code" | awk '{print $NF}'

关于如何实际执行此操作的任何想法?

4

6 回答 6

29

A general answer for grep-ing the grep-ed output:

grep 'patten1' *.txt | grep 'pattern2' 

notice that the second grep is not pointing at a file.

More about cool grep stuff here

于 2014-09-08T14:54:19.997 回答
7

您快到了。但是,虽然 xargs 有时可以用来做你想做的事(取决于下一个命令如何接受它的参数),但你实际上并没有使用它来 grep 你刚刚提取的 ID。您需要做的是获取第一个 grep 的输出(包含 ID 代码)并在下一个 grep 的表达式中使用它。就像是:

grep "^ID `grep 'xyz occured' file.log | awk '{print $2}'` status code" file.log

显然,另一种选择是编写一个脚本一次性完成此操作,a-la Ed 的建议。

于 2013-02-06T17:57:47.623 回答
1

Grep 上一次 Grep 的结果:

鉴于此文件内容:

ID 1000 xyz occured
ID 1001 misc content
ID 1000 misc content
ID 1000 status code: 26348931276572174
ID 1000 misc content
ID 1001 misc content

这个命令:

grep "xyz" file.log | awk '{ print $2 }' > f.log; grep `cat f.log` file.log;

返回这个:

ID 1000 xyz occured
ID 1000 misc content
ID 1000 status code: 26348931276572174
ID 1000 misc content

它在 file.log 中查找“xyz”,将结果放在 f.log 中。然后在 file.log 中用 greps 查找该 ID。如果外部 grep 返回多个 ID 号,则内部 grep 将仅搜索第一个 ID 号并在其他 ID 号上出错。

于 2013-02-06T17:57:04.947 回答
1

还有一种方式

for x in `grep "xyz occured" file.log | cut -d\  -f2`
do
  grep $x file.log
done

我喜欢这种方法的一点是,如果您愿意,您可以将每个状态代码的输出写入文件。

grep $x file.log >> /var/tmp/$x.out
于 2013-08-12T04:04:18.963 回答
1

只需使用 awk:

awk '{info[$2] = info[$2] $0 ORS} /xyz occured/{ids[$2]} END{ for (id in ids) printf "%s",info[id]}' file.log

或者:

awk '/status code/{code[$2]=$NF} /xyz occured/{ids[$2]} END{ for (id in ids) print code[id]}' file.log

取决于您真正想要输出的内容。您问题中的一些预期输出会有所帮助。

于 2013-02-06T17:51:52.777 回答
1

这都是关于在缩小的搜索范围内检索文件。在您的情况下,搜索范围由文件内容确定。

我在通过许多搜索(将过滤器应用于以前的 grep 结果)缩小搜索范围时更经常地发现了这个问题。

试图找到一般答案

1) 使用第一个 grep 的结果生成一个列表:

grep pattern | awk -F':' '{print $1}'

2)第二个 grep 进入像这里这样的文件列表

xargs grep -i pattern

3) 应用此级联过滤器,您只需添加 awk 即可仅获取文件名并将xargs文件名传递给 grep -i

例如:

grep 'pattern1' | awk -F':' '{print $1}' | xargs grep -i 'pattern2'
于 2015-09-20T11:55:23.180 回答