bash Grep 并打印回参考

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15067796/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 04:39:44  来源:igfitidea点击:

Grep and print back reference

bashshellgrepiptables

提问by w00d

I have this iptable log:

我有这个 iptable 日志:

Feb 25 10:32:48 XXX: [414645.555838] FW: DEN TCP IN=eth0 OUT= MAC=XYZ SRC=1.1.1.1 DST=2.2.2.2 LEN=40 TOS=0x00 PREC=0x00 TTL=57 ID=0 DF PROTO=TCP SPT=80 DPT=51814 WINDOW=0 RES=0x00 RST URGP=0

I want to grep 1.1.1.1 and 80 (SRC and SPT field). I do this:

我想 grep 1.1.1.1 和 80(SRC 和 SPT 字段)。我这样做:

grep -oP 'SRC=([^ ]+).+SPT=([0-9]+)' /var/log/iptables.log

But it returns:

但它返回:

SRC=1.1.1.1 DST=2.2.2.2 LEN=40 TOS=0x00 PREC=0x00 TTL=57 ID=0 DF PROTO=TCP SPT=80

How do I get $1 and $2 only ( reference to the matched value)?

如何仅获得 $1 和 $2(参考匹配值)?

回答by Thor

The main issue with your example is that you are trying to return groupings, this is not possible IIUC. One way around this is to use positive look-behind (see man perlre):

您的示例的主要问题是您正在尝试返回分组,这是不可能的 IIUC。解决此问题的一种方法是使用正向后视(请参阅 参考资料man perlre):

grep -oP '(?<=SRC=|SPT=)[^ ]*'

Output:

输出:

1.1.1.1
80

Here's a more portable alternative:

这是一个更便携的替代方案:

grep -o 'SRC=[^ ]*\|SPT=[^ ]*' | grep -o '[^=]*$'

If you want the output to be on one line, you should consider going one tool up, i.e. use Lev'sanswer. If you know that the output always comes in pairs, you could join the lines with paste:

如果您希望输出在一行上,您应该考虑使用一种工具,即使用Lev 的答案。如果您知道输出总是成对出现,您可以将这些行加入paste

grep -oP '(?<=SRC=|SPT=)[^ ]*' | paste - -

Or with xargs:

或与xargs

grep -oP '(?<=SRC=|SPT=)[^ ]*' | xargs -n2

Or sed:

sed

grep -oP '(?<=SRC=|SPT=)[^ ]*' | sed 'N; s/\n/ /'

回答by Lev Levitsky

A sedapproach:

一种sed做法:

sed -rn 's/.*SRC=([^ ]+).*SPT=([0-9]+).*/ /p' /var/log/iptables.log

You can pipe it to while read src sptin your script or something similar. Now this of course is not very efficient, because of three stars in the pattern, so if performance is an issue, you can consider using things like cutto extract certain fields:

您可以将其通过管道传输到while read src spt脚本或类似内容中。现在这当然不是很有效,因为模式中的三颗星,所以如果性能是一个问题,你可以考虑使用诸如cut提取某些字段之类的东西:

cut -d' ' -f12,21 /var/log/iptables.log

Not sure if the log format is consistent enough for this to work.

不确定日志格式是否足够一致以使其正常工作。