【问题标题】:printing after retrieving all the required fields using awk/sed/bash使用 awk/sed/bash 检索所有必填字段后打印
【发布时间】:2019-04-04 02:26:57
【问题描述】:

寻找使用 awk/sed/bash 以所需格式打印的正确方法。

考虑一个包含以下内容的文件 (awk_test.txt),

Checkpoint number: ckpt.123
value1: 10
value2: 10
Checkpoint number: ckpt.234
value1: 20
value2: 25

如何从文件中提取数据并在新行中按以下格式打印?

ckpt.123,10,10
ckpt.234,20,25

我尝试了以下 awk 命令,但没有全部打印出来。

awk < awk_test.txt '/ckpt/{a=$NF} /value1/{b=$NF} /value2/{c=$NF} END {printf "%s,%s,%s\n",a,b,c}'

【问题讨论】:

    标签: linux bash awk sed


    【解决方案1】:
    $ awk '/^Check/{if (NR>1) print rec; rec=$NF; next} {rec = rec "," $NF} END{print rec}' file
    ckpt.123,10,10
    ckpt.234,20,25
    

    【讨论】:

      【解决方案2】:

      对于 GNU awk,Record Separator RS 可以设置为任何正则表达式,在这种情况下,可以设置为 Checkpoint number。字段分隔符 FS 可以设置为:\n。 这样行就变成了字段。

      gawk 'BEGIN{ RS="Checkpoint number" ; FS=": |\n"; OFS="," } { if(NR > 1){ print $2,$4,$6 }}' text.txt
      

      结果:

      ckpt.123,10,10
      ckpt.234,20,25
      

      注意:POSIX 仅支持单个字符作为 RS。感谢@EdMorton 和@Rafael 的cmets。我不习惯考虑便携性。

      【讨论】:

      • wrt Record Separator RS can be set to any string - 没有。在 POSIX awks 中,RS 是单个字符,而在 GNU awk 中,它是一个多字符正则表达式,它绝不是文字多字符字符串。
      • @EdMorton 在考虑可移植性时,这绝对是一个重要因素。在为自己辩护时,他调用了gawk,但从未说过awk
      • @Rafael 调用 gawk 并没有告诉读者该代码只能在 gawk 中工作,它只是告诉读者张贴者恰好使用 gawk,即使在 gawk 中,RS 也不是“ string" 这是一个正则表达式。
      【解决方案3】:

      您只能打印END 块中的数据。当然,您需要结束块,但是当您到达ckpt 行并且已经积累了一些数据时,您还需要打印。这导致:

      awk '/ckpt/   { if (a != "") printf "%s,%s,%s\n", a, b, c; a = $NF }
           /value1/ { b = $NF }
           /value2/ { c = $NF }
           END      { printf "%s,%s,%s\n", a, b, c }'
      

      当用于您的样本数据时,会产生:

      ckpt.123,10,10
      ckpt.234,20,25
      

      或者你甚至可以使用一个函数来封装打印:

      awk 'function print_it() { printf "%s,%s,%s\n", a, b, c; }
           /ckpt/   { if (a != "") print_it(); a = $NF}
           /value1/ { b = $NF }
           /value2/ { c = $NF }
           END      { print_it() }'
      

      这样做的好处是可以确保在需要打印的两个地方使用相同的打印代码。

      【讨论】:

        【解决方案4】:

        这可能对你有用(GNU sed):

        sed -r 's/.*: //;N;N;s/\n[^:]*: /,/g' file
        

        删除标签并用逗号替换换行符以换行模三。

        【讨论】:

          猜你喜欢
          • 2020-06-22
          • 2017-11-12
          • 2020-04-26
          • 2013-03-13
          • 1970-01-01
          • 1970-01-01
          • 2016-04-05
          • 2021-07-02
          • 1970-01-01
          相关资源
          最近更新 更多