从特定行开始,打印与模式匹配的周围行

Starting at particular line, print surrounding lines that match pattern

如果我返回 diff 显示,例如:

7c7
< backup=false
---
> backup=true

我怎样才能打印出与模式 "where the quoted Tags string starts and ends" 匹配的周围线条?例如,对于下面的文本,如果第 7 行发生更改,我想获取该行中包含的内容 + 包含引号字符串的行,该字符串跨越未知行数:

示例文本(原创):

Name    Monitoring  Tags
i-RBwPyvq8wPbUhn495 enabled "some:tags:with:colons=some:value:with:colons-and-dashes/and/slashes/yay606-values-001
some:other:tag:with-colons-and-hyphens=MACHINE NAME 
Name=NAMETAG    
backup=true"
i-sMEwh2MXj3q47yWWP enabled "description=RANDOM BUSINESS INT01  
backup=false    
Name=SOMENAME"

示例文本(更改):

Name    Monitoring  Tags
i-RBwPyvq8wPbUhn495 enabled "some:tags:with:colons=some:value:with:colons-and-dashes/and/slashes/yay606-values-001
some:other:tag:with-colons-and-hyphens=MACHINE NAME 
Name=NAMETAG    
backup=true"
i-sMEwh2MXj3q47yWWP enabled "description=RANDOM BUSINESS INT01  
backup=true 
Name=SOMENAME"

...我想以某种方式 return:

i-sMEwh2MXj3q47yWWP   enabled "description=RANDOM BUSINESS INT01  
backup=true   
Name=SOMENAME"

使用用于多字符 RS 和 BEGINFILE 的 GNU awk,这将简单地将每个多行记录视为一个记录,而不是单独地处理其组成行:

$ cat tst.awk
BEGINFILE {
    # make sure RS is the default so we can read/skip each header line
    RS="\n"
}

FNR==1 {
    # skip the header line and set RS to capture multi-line records
    RS="[^\"]+\"[^\"]+\"\n"
    next
}

# at this point each record is stored in RT instead of [=10=]

NR==FNR {
    a[FNR] = RT
    next
}

RT != a[FNR] {
    printf "Record #%d:\n", FNR-1
    printf "< %s", a[FNR]
    printf "> %s", RT
}

.

$ awk -f tst.awk orig change
Record #2:
< i-sMEwh2MXj3q47yWWP enabled "description=RANDOM BUSINESS INT01
backup=false
Name=SOMENAME"
> i-sMEwh2MXj3q47yWWP enabled "description=RANDOM BUSINESS INT01
backup=true
Name=SOMENAME"

已更新为使用 "Name" 列作为唯一标识符,请参阅以下评论:

$ cat tst.awk
BEGINFILE {
    # make sure RS is the default so we can read/skip each header line
    RS="\n"
}

FNR==1 {
    # skip the header line and set RS to capture multi-line records
    RS="[^\"]+\"[^\"]+\"\n"
    next
}

# at this point each record is stored in RT instead of [=12=]
{ [=12=]=RT }

NR==FNR {
    a[] = [=12=]
    next
}

{
    if (  in a ) {
        if ( [=12=] != a[] ) {
            printf "Record %s changed:\n", 
            printf "< %s", a[]
            printf "> %s", [=12=]
        }
        delete a[]
    }
    else {
        printf "Record %s added:\n", 
        printf "> %s", [=12=]
    }
}
END {
    for ( i in a ) {
        printf "Record %s deleted:\n", i
        printf "< %s", a[i]
    }
}

.

$ awk -f tst.awk orig change
Record i-sMEwh2MXj3q47yWWP changed:
< i-sMEwh2MXj3q47yWWP enabled "description=RANDOM BUSINESS INT01
backup=false
Name=SOMENAME"
> i-sMEwh2MXj3q47yWWP enabled "description=RANDOM BUSINESS INT01
backup=true
Name=SOMENAME"