簡単にするためにパターンを一致させた後、ファイル全体を編集したいと思います。ファイルの例は次のとおりです。
$ 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の場合と同じ構造を持たない可能性があることです。ip
とmask
情報の間にいくつかのテキストがあるため、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
戻して前に戻ります。