【问题标题】:Dot delimited parsing with awk使用 awk 进行点分隔解析
【发布时间】:2020-01-25 14:30:32
【问题描述】:

我有一个命令的输出,如下所示:

hw.sensors.cpu0.temp0=39.00 degC
hw.sensors.acpitz0.temp0=27.80 degC (zone temperature)

所需的awk 输出如下:

# TYPE hw_sensors gauge
hw_sensors{sensor="cpu0" reading="temp0"} 39
hw_sensors{sensor="acpitz0" reading="temp0"} 27

我现在的想法有点混乱(我不是awk guru!),所以到目前为止我的努力看起来是这样的:

sysctl hw.sensors | fgrep temp0 | sed 's/\./_/g' | awk '{FS="="; print "# TYPE "$1" gauge\n"$1" "$2}' | sed -E 's/_[[:digit:]]{1,2}.*$//g' 

我想我可以继续使用更多管道,但这很可能是错误的方法!

【问题讨论】:

    标签: awk sh


    【解决方案1】:

    假设对 temp0 的测试确实是必要的,并且您的输入可以包含多种类型的报告:

    sysctl hw.sensors |
    awk -F'[.=]' '
        !/temp0/ { next }
        { type = $1 "_" $2 }
        !doneHdr[type]++ { printf "# TYPE %s gauge\n", type }
        { printf "%s{sensor=\"%s\" reading=\"%s\"} %d\n", type, $3, $4, $5 }
    '
    # TYPE hw_sensors gauge
    hw_sensors{sensor="cpu0" reading="temp0"} 39
    hw_sensors{sensor="acpitz0" reading="temp0"} 27
    

    【讨论】:

      【解决方案2】:

      请您尝试关注一下。

      awk -F'[.=]' -v s1="\"" '{print $1"_"$2"{"$2"="s1 $3 s1 " reading="s1 $4 s1 "} " $5+0}' Input_file
      

      【讨论】:

        【解决方案3】:

        这对您来说可能是最简单且适应性最强的:

        awk 'BEGIN{FS="="}'
             {key=$1; value=$2}
             {split(key,k,/[.]/)}
             {split(value,v)}
             {print k[1]"_"k[2]"{sensor=\042" k[3] "\042 reading=\042"k[4]"\042}",v[1]}'
        

        这通过以下方式工作:

        1. 将每一行拆分成一个键值对:

          line: hw.sensors.cpu0.temp0=39.00 degC
          => key=hw.sensors.cpu0.temp0
          => value=39.00 degC
          
        2. 根据点作为分隔符将键拆分为子部分,将部分存储在数组k中:

          key=hw.sensors.cpu0.temp0
          split(key,k,/[.]/)
          => k=(hw,sensor,cpu0,temp0)
          
        3. 以空格为分隔符将值拆分为子部分,将数组v中的部分分开:

          value=39.00 degC
          split(value,v)
          => k=(39.00,degC)
          
        4. 按照你喜欢的方式重新组装零件:

          print k[1]"_"k[2]"{sensor=\042" k[3] "\042 reading=\042"k[4]"\042}",v[1]
          

        这种方法非常灵活,你现在可以在零件上设置条件来确定重新组装规则:示例:

        (k[2]=="sensor"){ print k[1]"_"k[2]"{sensor=\042" k[3] "\042 reading=\042"k[4]"\042}",v[1] }
        (k[2]=="dog") { print "This dog is",v[1], "cm long" }
        

        【讨论】:

          【解决方案4】:

          通过使用.= 作为使用awk 的字段分隔符,使用列3,4,5

          sysctl hw.sensors | awk -F'[.=]' -v fmt='hw_sensors{sensor="%s" reading="%s"} %d\n' '/temp0/{ printf(fmt,$3,$4,$5) }'
          

          可读性更好的版本

          sysctl hw.sensors | \
          awk -F'[.=]' -v fmt='hw_sensors{sensor="%s" reading="%s"} %d\n' '
          /temp0/{ 
               printf(fmt,$3,$4,$5) 
          }'
          

          说明

          • -F'[.=]'设置字段分隔符
          hw.sensors.cpu0.temp0=39.00 degC
          ^    ^       ^    ^    ^  ^
          col1 col2   col3 col4 col5 col6
          
          • -v fmt='hw_sensors{sensor="%s" reading="%s"} %d\n' 变量fmt 包含格式字符串,类似于c/c++
          • /temp0/{ 搜索行/行/记录包含temp0
          • printf(fmt,$3,$4,$5)最后打印你的字段

          【讨论】:

            猜你喜欢
            • 2013-03-03
            • 2017-01-18
            • 1970-01-01
            • 1970-01-01
            • 2020-09-13
            • 1970-01-01
            • 2014-06-24
            • 1970-01-01
            • 2010-11-29
            相关资源
            最近更新 更多