AWKを使用してテキストブロックを見つけ、その中の文字列を置き換えます。

AWKを使用してテキストブロックを見つけ、その中の文字列を置き換えます。

1つ以上のリソースブロックを見つけて変更または欠落している場合に追加する必要があるTerraformファイルがあります。

入力サンプル- 2つのチャンクで構成されるファイルの例(ただし、各セクションにはより多くのデータ行がある可能性があります):

resource "aws_instance" "ec2" {
    ami = "ami-0579a2723154bfc44"
    instance_type = "t2.micro"
    count = 1

    tags {
        Type = "ec2"
        By = "Terraform"
    }
}

resource "aws_instance" "ec2" {
    ami = "ami-blahblah"
    instance_type = "t2.micro"
    count = 1
}

期待される出力- 上記を考慮すると、次のような結果が出ると予想されます。

resource "aws_instance" "ec2" {
    ami = "ami-0579a2723154bfc44"
    instance_type = "t2.micro"
    count = 1

    tags = merge(
    var.tags,
    map(
        Type = "ec2"
        By = "Terraform"
        )
    )
}

resource "aws_instance" "ec2" {
    ami = "ami-blahblah"
    instance_type = "t2.micro"
    count = 1

    tags = merge(
    var.tags,
    map(
        Type = "ec2"
        By = "Terraform"
        )
    )
}

したがって、中括弧の代わりに中括弧が必要です。マージ、変数ラベルそして地図(。もしなければ商標しかし、ブロックを追加する必要があります(おそらく簡単になります)。特定のユースケースをキャプチャできるようにbashスクリプトを作成しました。

declareリソースブロックにタグ情報がない場合に備えて、bashスクリプトにタグ情報を含むファイルを追加しました。しかし、より簡単に作成できる場合は、ここで他のソリューションを使用する方がはるかにうれしいです。

ARRAY=( "Type:ec2"
        "By:Terraform")

現在のリソースブロックを見つけるために使用するawkは次のとおりです(「i」は0で始まり、「k」は1で始まります)。

awk '/^resource "/ {i++}; i=='$i' && k=='$k' {print}; /^}/ {k++}' file

誰かが私にヒントを与えることができますか?各ユースケース(タグの交換または新しいタグの追加)ごとに異なるawkを使用する必要があるようです。多くの同様のファイルを確認して最初にsedで試してみましたが、失敗してからawkで試してみたので、実際に正しいツールになることを願っています。

ありがとうございます!

ベストアンサー1

シェル配列の値がARRAY目的の出力形式と一致しません。以下では、awk配列をデフォルトとして使用し、目的の出力形式を使用しています。また、入力ファイルの最初のラベルブロックにすでに存在していたものとは異なる値を使用したため、出力からその値がどこから来たのかが明確でした。

$ cat tst.awk
BEGIN {
    split("Type = \"bikini bottom\"" RS "By = \"Sponge Bob\"",dlftMap,RS)
    dfltIndent = "   "
}

$1 == "tags" {
    inTags = 1
    gotTags = 1
    indent = $0
    sub(/[^[:space:]].*/,"",indent)
    print indent "tags = merge("
    print indent "var.tags,"
    print indent "map("
    next
}

inTags && ($1 == "}") {
    print indent dfltIndent ")"
    print indent ")"
    inTags = 0
    next
}

$1 == "}" {
    if ( !gotTags ) {
        print ""
        print indent "tags = merge("
        print indent "var.tags,"
        print indent "map("
        for (i=1; i in dlftMap; i++) {
            print indent dfltIndent dlftMap[i]
        }
        print indent dfltIndent ")"
        print indent ")"
    }
    gotTags = 0
}

{ print }

$ awk -f tst.awk file
resource "aws_instance" "ec2" {
    ami = "ami-0579a2723154bfc44"
    instance_type = "t2.micro"
    count = 1

    tags = merge(
    var.tags,
    map(
        Type = "ec2"
        By = "Terraform"
       )
    )
}

resource "aws_instance" "ec2" {
    ami = "ami-blahblah"
    instance_type = "t2.micro"
    count = 1

    tags = merge(
    var.tags,
    map(
       Type = "bikini bottom"
       By = "Sponge Bob"
       )
    )
}

おすすめ記事