2017-05-17 10 views
0

指定された条件で行グループを2回印刷し、行の値を変更するオプションを繰り返すAWK文を作成するのは困難です。たとえば、行の最初のフィールドが11($ 1 = 11)の場合、その行と2番目の行($ 2)の値を調整して印刷したいと考えています($ 2)。条件が満たされた場合、AWKの行グループが2回表示されます

Soここまでは、私が持っているものですが、それは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 

これは何の簡易版であります私はしたいと思いますので、単純なことを言いましょう都市私は$ 1 == 11で2番目の列($ 2)の値を元の値の半分にするために行(NR + 1)に続く印刷されたNRを希望します。例:1 3セクションの下の行をグループ化する場合、11の後の値は0.5です。理想的には、印刷された行は11に続く値が0.25になります。 GNU AWKで

理想的な出力

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 

答えて

2

gensubのための()と\ S/\ S:

$ 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 
+0

しかし、私はまだだ、これは便利です(PS入力ファイル内のスペースを先頭と末尾の。私はむしろNFの== 3よりもNF> 2 & & NF = 5 <を使用しなければならなかった理由ですが。あります) 11. – platypus106

+0

と一緒に保存された行の調整済みバージョンを印刷する際に問題がありますが、11行の行に対して保存された行の調整版を印刷する際に問題があります。$ 0から$ 1にsを変更してもたとえば、最初に行11が印刷されるのは、元の行の読み込みと同じです。ここでは、調整済みの2つのバージョン(s = $ 1、$ 0ではなく)のみを印刷します。 11で始まるときに元の行をスキップして、調整されたバージョンのみを印刷する方法はありますか? 'awk '1; s {ORS $ 0; s = ""} $ 1 == 11 {s = $ 1; v = 0;} '' – platypus106

+0

私はあなたの質問にフィールドを変更することに気づいていませんでした。私は私の答えを更新しました。 –

0

次のawkスクリプトを使用することができます。

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; 
    } 
} 
関連する問題