grepパターンを一致させた後にファイル全体を編集するには?

grepパターンを一致させた後にファイル全体を編集するには?

簡単にするためにパターンを一致させた後、ファイル全体を編集したいと思います。ファイルの例は次のとおりです。

$ cat file
ip=x.x.x.a
mask=255.0.0.0
host=a
ip=x.x.x.b
mask=255.0.0.0
host=b
ip=x.x.x.c
mask=255.0.0.0
host=c
ip=x.x.x.x
blahblah
mask=255.0.0.0
host=d

ホストcのIPを編集したいのですが、変数がある可能性があるので値がわからないとしましょう。その行を印刷するgrep host cために使用すると、元の-B2ファイルで編集することはできません!別の点は、行がホストdの場合と同じ構造を持たない可能性があることです。ipmask情報の間にいくつかのテキストがあるため、IPパターンが常に私の検索パターンより2行前にあるとは限りません。

まだIPがわからないので、直接grepすることはできませんが、代わりにホストを検索してこの一致の前に行を編集してIP値を変更する必要があります。どうすればいいですか?

ベストアンサー1

ファイルを後ろに移動すると、はるかに簡単になります。幸いなことに、これは簡単に行うことができますtac(リバースタスクですcat)。その後、比較的簡単なawkスクリプトを使用して目的のスクリプトを見つけてhost変更できますip

$ tac input | awk -v OFS="=" -v myip="changed_address" -v myhost="d" -F"=" '$1 == "host" { if( $2 == myhost ) { sw = "on" } else { sw="off" } } sw == "on" && $1 == "ip" { $2=myip } { print $0 }' | tac
ip=x.x.x.a
mask=255.0.0.0
host=a
ip=x.x.x.b
mask=255.0.0.0
host=b
ip=x.x.x.c
mask=255.0.0.0
host=c
ip=changed_address
blahblah
mask=255.0.0.0
host=d

awkどのように機能するかを詳しく説明します。

まず、いくつかの変数を宣言します。各変数はforhostで、新しい値は次のとおりですip

-v myip="changed_address" -v myhost="d"

また、入力と出力のフィールド区切り文字を宣言します。

-v OFS="=" -F"="

実際のawkスクリプト自体は次のようになります。

$1 == "host" {             // If we see the "host" line..
  if( $2 == myhost ) {     // And it matches the one we're looking for..
    sw = "on"              // Set a flag to swap the next IP
  } else { 
    sw="off"               // Otherwise, unset the flag
  }
} 

sw == "on" && $1 == "ip" { // If the flag is set and this is an IP line.. 
    $2=myip                // Swap in the new IP 
}

{
   print $0                // Finally, print out the processed line
}

すべての操作が完了したら、もう一度使用して元にtac戻して前に戻ります。

おすすめ記事