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 스크립트를 작성했습니다.

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"
       )
    )
}

관련 정보