【问题标题】:AWK print group of lines twice if conditions met如果条件满足,AWK 打印行组两次
【发布时间】:2017-05-18 23:13:14
【问题描述】:

我在编写 AWK 语句时遇到困难,该语句将在指定条件下两次打印出一组行,并且可以选择更改重复行中的值。例如,如果一行的第一个字段是 11 ($1=11),那么我想将该行和后面的行打印两次(调整第二列 ($2) 中的值。

到目前为止,这就是我所拥有的,但它不会复制第一个字段 = 到 11 和以下行的行。

awk '{if(NF<3) print $0; if(NF==3 && $1==11) print $0, 1, 20; if(NF==3 && $1 != 11) print $0, 0, 0; if(NF>3) print $0;}'

输入示例

1 3
            6 0.1 99 
              0.100 0.110 0.111 
            7 0.4 88 
              0.200 0.220 0.222
           11 0.5 77
              0.300 0.330 0.333 
2 2
            7 0.3 66
              0.400 0.440 0.444 
           11 0.7 55
              0.500 0.550 0.555  

这是我想做的简化版本,所以为了简单起见,我希望打印的 NR 其中 $1==11 和下一行 (NR+1) 具有第二列中的值 ( $2) 是原始价值的一半。例如,对于 1 3 部分下的行分组,11 之后的值为 0.5。理想情况下,打印出的行将具有 11 之后的值为 0.25。

理想输出

1 3
                6 0.1 99 0 0
                  0.100 0.110 0.111 
                7 0.4 88 0 0
                  0.200 0.220 0.222
               11 0.25 77 1 20
                  0.300 0.330 0.333 
               11 0.25 77 1 20 
                  0.300 0.330 0.333 
2 2
                7 0.3 66 0 0
                  0.400 0.440 0.444 
               11 0.35 55 1 20
                  0.500 0.550 0.555  
               11 0.35 55 1 20
                  0.500 0.550 0.555  

【问题讨论】:

    标签: bash gawk awk


    【解决方案1】:

    对于 gensub() 和 \s/\S:使用 GNU awk:

    $ awk '$1==11{$0=gensub(/^(\s+\S+\s+)\S+/,"\\1"$2/2,1); c=2; s=$0} {print} c&&!--c{print s ORS $0}' file
    1 3
                6 0.1 99
                  0.100 0.110 0.111
                7 0.4 88
                  0.200 0.220 0.222
               11 0.25 77
                  0.300 0.330 0.333
               11 0.25 77
                  0.300 0.330 0.333
    2 2
                7 0.3 66
                  0.400 0.440 0.444
               11 0.35 55
                  0.500 0.550 0.555
               11 0.35 55
                  0.500 0.550 0.555
    

    【讨论】:

    • 这很有帮助,但是我仍然在打印带有 11 的行的已保存行的调整版本时遇到问题。
    • 这很有帮助,但是我仍然在打印带有 11 的行的已保存行的调整版本时遇到问题。例如,即使我将 s 从 $0 更改为 $1 - 第一次第 11 行是打印它与原始读取的行中的相同,我只想打印 2 个调整后的版本(其中 s = $1,而不是 $0)。从11开始有没有办法跳过打印原行,只打印调整后的版本? awk '1; s{print s ORS $0;s=""} $1==11{s= $1; v= 0;}'
    • 我没有注意到您问题中关于修改字段的部分。我已经更新了我的答案。
    【解决方案2】:

    您可以使用以下 awk 脚本。 (P.S. 您的输入文件中有前导和尾随空格。这就是为什么我必须使用 NF>2 && NF

    BEGIN {
        c=0;FS="[ \t]+";OFS=" ";x="";y="";
    }
    c==2{
        print x, 1, 20;
        print y;
        c=0;
    }
    NF ==2{
        print $0;
    }
    NF>2 && NF<=5{
        if(c==1){
            print $0;
            y=$0;c=2;next;
        }
        if($2==11){
            print $0, 1, 20;
            x=$0;c=1;
        }
        else print $0;
    
    }
    NF>5{
        print $0,"hello";
    }
    END{
        if(c==2){
            print x, 1, 20;
            print y;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      • 1970-01-01
      • 2014-04-09
      • 2019-02-09
      • 1970-01-01
      • 2015-11-15
      • 1970-01-01
      相关资源
      最近更新 更多