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

时间:2018-02-12 16:25:10

标签: awk grep diff

如果我找回显示的diff,例如:

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

那么我怎样才能打印出与“引用的标签字符串开始和结束的位置”模式匹配的周围线条?例如,使用下面的文本,如果第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"

......我想以某种方式返回:

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

1 个答案:

答案 0 :(得分:2)

对于多字符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 $0

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"

更新为使用“名称”列作为唯一标识符,请参阅以下注释:

$ 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 $0
{ $0=RT }

NR==FNR {
    a[$1] = $0
    next
}

{
    if ( $1 in a ) {
        if ( $0 != a[$1] ) {
            printf "Record %s changed:\n", $1
            printf "< %s", a[$1]
            printf "> %s", $0
        }
        delete a[$1]
    }
    else {
        printf "Record %s added:\n", $1
        printf "> %s", $0
    }
}
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"