【问题标题】:How to use multiple delimiters in awk?如何在awk中使用多个分隔符?
【发布时间】:2018-04-08 09:53:00
【问题描述】:

我想用 awk 用冒号分割一个变量,但只有最后一个变量。

从此输入:

 ACCEPT     tcp  --  0.0.0.0/0     0.0.0.0/0     tcp dpt:22

我想要以下输出:

 protocol=tcp source=0.0.0.0/0 destination=0.0.0.0/0 port=22

这是我现在的 awk 命令:

 awk '/^ACCEPT/ {print "protocol=",$2, "source=",$4,"destination=",$5,"port=",$7}"

产生:

protocol=tcp source=0.0.0.0/0 destination=0.0.0.0/0 port=dpt:22

但我想从$7 中获得22 而不是dpt:22

我尝试过使用 awk 的字段分隔符,但我可以弄清楚如何使其仅适用于单个变量

【问题讨论】:

  • 没有分号。 : 是冒号,; 是分号。
  • 您是否尝试过使用split() 功能?该名称就在您的问题标题中。
  • AWK multiple delimiter的可能重复

标签: linux bash awk


【解决方案1】:

使用以下 awk 方法:

awk '{ printf "protocol=%s source=%s destination=%s port=%s\n",$2,$4,$5,substr($7,5) }' file

但如果最后一个字段具有动态 前缀 长度,您可以应用 gsub() 函数来删除非数字字符:

awk '{ gsub(/^[^0-9]+/,"",$7); printf "protocol=%s source=%s destination=%s port=%s\n",$2,$4,$5,$7 }' file

【讨论】:

    【解决方案2】:

    您可以使用正则表达式在awk 中定义自定义字段分隔符。

    some_command | awk -F '[[:blank:]:]+' '/^ACCEPT/{
       printf "protocol=%s source=%s destination=%s port=%s\n", $2, $4, $5, $NF}'
    
    protocol=tcp source=0.0.0.0/0 destination=0.0.0.0/0 port=22
    

    -F '[[:blank:]:]+' 将输入字段分隔符设置为空格或冒号之一。

    【讨论】:

      【解决方案3】:

      awk 命令稍作修改

      $ awk '/^ACCEPT/ {gsub(/[^0-9]/,"",$7); print "protocol="$2, "source="$4,"destination="$5,"port="$7}' file
      protocol=tcp source=0.0.0.0/0 destination=0.0.0.0/0 port=22
      

      gsub(/[^0-9]/,"",$7); 将使$7 中的所有非数字字符无效

      【讨论】:

        【解决方案4】:

        只需调整 FS 以包含:

        $ echo 'ACCEPT     tcp  --  0.0.0.0/0     0.0.0.0/0     tcp dpt:22' |
             awk '/^ACCEPT/{printf("protocol=%s source=%s destination=%s port=%s\n", $2,$4,$5,$8)}
             ' FS='[ :]*'
        protocol=tcp source=0.0.0.0/0 destination=0.0.0.0/0 port=22
        

        您可能需要包含标签,然后执行FS='[ :\t]*'

        【讨论】:

          【解决方案5】:

          awk 有一个 split 函数,可以使用指定的分隔符正则表达式(参数 3)将字符串(参数 1)分解为字段数组(参数 2)。

          以下 awk 程序将扫描所有 iptables 选项(字段 6 到行的最后一个字段),而不是依赖 dpt:### 作为第 7 个字段。

          awk '/^ACCEPT/ {
                           port="???"
                           for (i=6; i<=NF; i++) {
                             if (split($i, opt, ":")==2 && opt[1]=="dpt") {
                                port=opt[2]
                             }
                           }
                           print "protocol=" $2, "source=" $4, "destination=" $5, "port=" port
                         }'
          

          【讨论】:

            猜你喜欢
            • 2012-08-25
            • 2022-01-13
            • 2014-07-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-01-06
            相关资源
            最近更新 更多