使用 AWK 查找文本块并替换其中的字符串

使用 AWK 查找文本块并替换其中的字符串

我有一个 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 脚本,以便能够捕获特定的用例。

我在 bash 脚本中添加了一个declare包含标签信息的文件,以防资源块没有标签信息。但我非常乐意在这里使用任何其他解决方案,如果它能让它变得更容易的话。

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

我当前用来查找资源块的 awk 是(“i”以 0 开头,“k”以 1 开头):

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

有人可以给我提示吗?我想我需要为每个用例使用不同的 awk(替换标签或添加新标签)。需要浏览许多类似的文件,并首先使用 sed 进行尝试,但失败了,然后使用 awk 进行了进一步的操作,因此希望它实际上是正确的工具。

谢谢!

答案1

shell 数组中的值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"
       )
    )
}

相关内容