【问题标题】:Cut delimiters in bash在 bash 中剪切分隔符
【发布时间】:2022-01-26 10:52:45
【问题描述】:

我正在尝试从日志文件中收集信息。目前我想找到最流行的 ip 源,特别是前 10 个包发送者。我的日志文件如下所示:

Feb 24 21:32:17 bridge kernel: INBOUND TCP: IN=br0 PHYSIN=eth0 OUT=br0 PHYSOUT=eth1 SRC=67.24.151.60 DST=11.11.11.69 LEN=48 TOS=0x00 PREC=0x00 TTL=115 ID=28482 DF PROTO=TCP SPT=3252 DPT=445 WINDOW=8760 RES=0x00 SYN URGP=0  
Feb 24 21:32:17 bridge kernel: INBOUND TCP: IN=br0 PHYSIN=eth0 OUT=br0 PHYSOUT=eth1 SRC=67.24.151.60 DST=11.11.11.69 LEN=48 TOS=0x00 PREC=0x00 TTL=115 ID=28534 DF PROTO=TCP SPT=3252 DPT=445 WINDOW=8760 RES=0x00 SYN URGP=0  
Feb 24 21:32:18 bridge kernel: INBOUND TCP: IN=br0 PHYSIN=eth0 OUT=br0 PHYSOUT=eth1 SRC=67.24.151.60 DST=11.11.11.69 LEN=48 TOS=0x00 PREC=0x00 TTL=115 ID=28575 DF PROTO=TCP SPT=3252 DPT=445 WINDOW=8760 RES=0x00 SYN URGP=0  
Feb 24 21:33:19 bridge kernel: INBOUND UDP: IN=br0 PHYSIN=eth0 OUT=br0 PHYSOUT=eth1 SRC=202.108.249.51 DST=11.11.11.100 LEN=404 TOS=0x00 PREC=0x00 TTL=114 ID=49546 PROTO=UDP SPT=1282 DPT=1434 LEN=384  
Feb 24 21:33:54 bridge kernel: Legal Broadcast: IN=br0 PHYSIN=eth1 OUT=br0 PHYSOUT=eth0 SRC=11.11.11.67 DST=11.11.11.255 LEN=241 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=138 DPT=138 LEN=221  
Feb 24 21:33:55 bridge kernel: Legal Broadcast: IN=br0 PHYSIN=eth1 OUT=br0 PHYSOUT=eth0 SRC=11.11.11.67 DST=11.11.11.255 LEN=232 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=138 DPT=138 LEN=212  
Feb 24 21:35:11 bridge kernel: INBOUND UDP: IN=br0 PHYSIN=eth0 OUT=br0 PHYSOUT=eth1 SRC=163.21.152.7 DST=11.11.11.67 LEN=69 TOS=0x00 PREC=0x00 TTL=45 ID=0 DF PROTO=UDP SPT=1812 DPT=1812 LEN=49  
Feb 24 21:36:12 bridge kernel: INBOUND TCP: IN=br0 PHYSIN=eth0 OUT=br0 PHYSOUT=eth1 SRC=4.34.188.37 DST=11.11.11.125 LEN=48 TOS=0x00 PREC=0x00 TTL=115 ID=16941 DF PROTO=TCP SPT=1649 DPT=445 WINDOW=16384 RES=0x00 SYN URGP=0  
Feb 24 21:36:13 bridge kernel: INBOUND TCP: IN=br0 PHYSIN=eth0 OUT=br0 PHYSOUT=eth1 SRC=4.34.188.37 DST=11.11.11.125 LEN=48 TOS=0x00 PREC=0x00 TTL=115 ID=17045 DF PROTO=TCP SPT=1649 DPT=445 WINDOW=16384 RES=0x00 SYN URGP=0  
Feb 24 21:36:14 bridge kernel: INBOUND TCP: IN=br0 PHYSIN=eth0 OUT=br0 PHYSOUT=eth1 SRC=4.34.188.37 DST=11.11.11.125 LEN=48 TOS=0x00 PREC=0x00 TTL=115 ID=17164 DF PROTO=TCP SPT=1649 DPT=445 WINDOW=16384 RES=0x00 SYN URGP=0  
Feb 24 21:36:16 bridge kernel: INBOUND TCP: IN=br0 PHYSIN=eth0 OUT=br0 PHYSOUT=eth1 SRC=61.41.216.94 DST=11.11.11.80 LEN=48 TOS=0x00 PREC=0x00 TTL=109 ID=1309 DF PROTO=TCP SPT=3179 DPT=445 WINDOW=16384 RES=0x00 SYN URGP=0

我构建了这个脚本:

    x=`grep "SRC=" $1 | cut -d " " -f13 | sed 's/\.[0-9]\+$//g' | sort -n | uniq -c | sort -n -r | head -n 10 `
    echo "${x}"

但是,在我的日志文件中,我的 Legal Broadcast 列搞砸了,因为我使用 " " 分隔符进行剪辑。有没有办法使用字符串作为剪切分隔符来过滤我的 ip srcs 而不是我当前使用的“”?

目前我的输出如下所示:

100398 PHYSOUT=eth1
12311 PHYSOUT=eth0
9454 SRC=11.11.11
8121 SRC=63.13.135
6394 SRC=127.0.0

应该是这样,包含与 SRC 及其 IP 一样多的软件包。然而,Legal Broadcast 的行似乎弄乱了顶部结果,显示了以前列中的信息。

【问题讨论】:

  • cut -d: -f3-?
  • 添加一个初步步骤:sed "s/Legal Broadcast/Legal_Broadcast/g"?完成后您可以撤消它
  • 请将该示例输入的所需输出(无描述、无图像、无链接)添加到您的问题(无评论)。
  • 您是在问如何排除“合法广播”行,或者如何从中获取SRC= 字段?前者对您的用例更有意义(源地址无论如何都是内部 IP),但您似乎忽略了澄清请求。
  • 我需要所有行的 SRC= 字段,包括 Legal Broardcast 行。然而,我构建它的方式,那些行(法律广播的)似乎把事情搞砸了。我需要 al SRC= 来查找前 10 个发件人 IP。很抱歉回复晚了。

标签: linux bash shell


【解决方案1】:

根据您提供的信息,很难猜出究竟什么会构成可接受的解决方案。您所描述的一个简单解决方法是跳过任何包含“合法广播”的行。

但是,无论如何,这些长序列几乎总是更好地重构为单个 Awk 脚本。

awk '/SRC=/ && !/Legal Broadcast/ { ip=$13; sub(/\.[0-9]*$/, "", ip); ++sum[ip] }
    END { for(net in sum) print sum[net], net }' "$1" |
sort -rn | head -n 10

如果您无法预测 SRC 字段的位置,您可以替换其他所有内容:


awk '/SRC=/ && !/Legal Broadcast/ { ip=$0; sub(/.* SRC=/, "", ip); sub(/\.[0-9]( .*)?$/, "", ip); ++sum[ip] }
    END { for(net in sum) print sum[net], net }' "$1" |
sort -rn | head -n 10

(如果你也想包含这些行,显然去掉!/Legal Broadcast/ 条件。)

捕获一个变量只是为了echo 这是一个useless use of echo 和(微小的)内存浪费。另请注意,sed/g 标志仅在您希望一行包含多个匹配项时才有意义(这对于您使用的正则表达式是不可能的)。

【讨论】:

    【解决方案2】:

    您只需使用 GNU awk 即可完成所有工作:

    gawk -F= -v RS=' ' 'BEGIN { PROCINFO["sorted_in"] = "@val_num_desc" }
            $1 ~ /^(SRC|PHYSOUT)$/ { ++a[$1 FS $2] }
            END { for (i in a) print a[i] "\t" i }' "$1"
    

    【讨论】:

      【解决方案3】:

      这可能是您正在寻找的:

      sed -n 's/.* SRC=\([^ ]*\)\..*/\1/p' "$1" | sort | uniq -c | sort -rn | head -n10
      

      【讨论】:

        猜你喜欢
        • 2014-07-03
        • 2015-11-10
        • 2019-08-29
        • 1970-01-01
        • 2013-11-18
        • 2022-01-05
        • 1970-01-01
        • 1970-01-01
        • 2020-08-08
        相关资源
        最近更新 更多