テキストファイルで繰り返されるブロック内で行を置き換える方法(sed / awkを使用する?)

テキストファイルで繰り返されるブロック内で行を置き換える方法(sed / awkを使用する?)

次のファイルがあります。

x = {
   y = {
       z = {
           block = {
              line1
              line2
              line3
           }
        }
    }
}
x2 = {
     y2 = {
         block = {
              line4
              line5
         }
     }
}
xyz
block = {
      line6
}

など。ブロック内の行を反転する必要がありますが、他のすべての項目は次のように順番に保持する必要があります。

x = {
   y = {
       z = {
           block = {
              line3
              line2
              line1
           }
        }
    }
}
x2 = {
     y2 = {
         block = {
              line5
              line4
              
         }
     }
}
xyz
block = {
      line6
}

sedまたはawkを使用してこれを行うには?ブロックを逆さまに反転しましたが、再び所定の位置に置くことはできません。

sed -n '/block = {.$/,/}$/p' inputfile | tac

ベストアンサー1

Perlを使っても大丈夫なら:

perl -ne 'if($f && /}/){$f=0; print @blk};
          $f ? unshift(@blk, $_) : print;
          if(/block = {/){$f=1; @blk=()}' ip.txt
  • if(/block = {/){$f=1; @blk=()}配列を初期化し、入力行に以下が含まれている場合に@blkフラグを設定します。$fblock = {
  • $f ? unshift(@blk, $_) : printこのフラグが有効な場合は配列の前に入力行を挿入し@blk、それ以外の場合は入力行を印刷します。
  • if($f && /}/){$f=0; print @blk}フラグが有効になっていて入力行に以下が含まれている場合は、フラグを設定解除して配列}の内容を印刷します。@blk

そしてawk

awk 'f && /}/{f=0; for(i=c; i>=1; i--) print blk[i]}
     {if(f) blk[++c] = $0; else print}
     /block = {/{f=1; c=0}' ip.txt

おすすめ記事