Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash Grep和打印回参考_Bash_Shell_Grep_Iptables - Fatal编程技术网

Bash Grep和打印回参考

Bash Grep和打印回参考,bash,shell,grep,iptables,Bash,Shell,Grep,Iptables,我有一个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 我想grep 1.1.1.1和80(SRC和SPT字段)。 我这样做: grep -o

我有一个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
我想grep 1.1.1.1和80(SRC和SPT字段)。 我这样做:

grep -oP 'SRC=([^ ]+).+SPT=([0-9]+)' /var/log/iptables.log
但它的回报是:

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

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

A
sed
方法:

sed -rn 's/.*SRC=([^ ]+).*SPT=([0-9]+).*/\1 \2/p' /var/log/iptables.log
您可以在脚本或类似内容中读取src spt时将其通过管道传输到
。当然,这并不是非常有效,因为模式中有三颗星,所以如果性能是一个问题,你可以考虑使用诸如<代码>剪切>代码>来提取某些字段:

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

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

您的示例的主要问题是您试图返回分组,这是不可能的。解决这个问题的一种方法是使用积极的回头看(请参见
man perlre
):

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

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

如果你想把输出放在一行上,你应该考虑使用一个工具,即使用列夫的答案。如果您知道输出总是成对出现,可以使用

paste

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

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

grep-oP'(?感谢sed解决方案,这是可行的。但我不敢相信grep没有这样的功能。要以类似grep的方式使用sed,请使用:
sed-n的/../…/p文件
,否则所有行都会被打印出来。@Pottong你说得对,在这种情况下,我想所有行都匹配,但无论如何我都会编辑。谢谢你没有我的grep so-1,sorryWell..谢谢你've
sed
it(…笑话..sed..ohh..无需担心..)您可以始终使用grep进行预设置,例如,使用
将您的查找限制为只找到第一个..grep--max count=1--仅匹配--扩展regexp'SRC=([^]+)。+SPT=([0-9]+)'| sed…
grep -oP '(?<=SRC=|SPT=)[^ ]*' | paste - -
grep -oP '(?<=SRC=|SPT=)[^ ]*' | xargs -n2
grep -oP '(?<=SRC=|SPT=)[^ ]*' | sed 'N; s/\n/ /'