【问题标题】:Grep and print back referencegrep 并打印回参考
【发布时间】:2013-02-25 13:11:52
【问题描述】:

我有这个 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(对匹配值的引用)?

【问题讨论】:

    标签: bash shell grep iptables


    【解决方案1】:

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

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

    输出:

    1.1.1.1
    80
    

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

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

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

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

    或者xargs:

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

    sed:

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

    【讨论】:

      【解决方案2】:

      sed 方法:

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

      您可以在您的脚本或类似的东西中将它传送到while read src spt。现在这当然效率不高,因为模式中有三颗星,所以如果性能有问题,可以考虑使用cut 之类的东西来提取某些字段:

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

      不确定日志格式是否足够一致。

      【讨论】:

      • 感谢 sed 解决方案,它有效。但我不敢相信 grep 没有这样的功能..
      • 要以类似 grep 的方式使用 sed,请使用:sed -n 's/.../.../p' file 否则将打印所有行。
      • @potong 你是对的,在这种情况下我猜所有的行都匹配,但我还是会编辑。谢谢
      • 那不是我的 grep 所以 -1,对不起
      • 嗯..你已经sed了它(..joke..说sed..哦..没关系..)你总是可以使用grep预sed ,例如,使用... | grep --max-count=1 --only-matching --extended-regexp 'SRC=([^ ]+).+SPT=([0-9]+)' | sed ... 将您的发现限制为仅第一个
      猜你喜欢
      • 1970-01-01
      • 2021-10-15
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多