5

如何在文本块中找到特定数字并打印以关键字开头并以 结尾的完整文本块?基本上这就是我的文件的样子:"BEGIN""END"

BEGIN
A: abc
B: 12345
C: def
END

BEGIN
A: xyz
B: 56789
C: abc
END

BEGIN
A: ghi
B: 56712
C: pqr
END

[...]

如果我正在寻找'^B: 567',我想得到这个输出:

BEGIN
A: xyz
B: 56789
C: abc
END

BEGIN
A: ghi
B: 56712
C: pqr
END

我可以在此处使用 grep ( grep -E -B2 -A2 "^B: 567" file),但我想获得更通用的解决方案。我猜awksed可能能够做到这一点!?

谢谢!:)

4

6 回答 6

9
$ awk -v RS= -v ORS='\n\n' '/\nB: 567/' file
BEGIN
A: xyz
B: 56789
C: abc
END

BEGIN
A: ghi
B: 56712
C: pqr
END

请注意\n之前的B内容,以确保它出现在一行的开头。这代替了^您最初拥有的字符串开头字符,因为现在每一行都不是它自己的字符串。您需要在上面设置 ORS 以重新插入记录之间的空行。

于 2013-10-09T11:06:40.133 回答
5

这可能对您有用(GNU sed):

sed -n '/^BEGIN/{x;d};H;/^END/{x;s/^B: 567/&/mp}' file

或这个:

sed -n '/^BEGIN/!b;:a;$!{N;/\nEND/!ba};/\nB: 567/p' file
于 2013-10-09T06:15:27.853 回答
2

您可以 undefRS以空行拆分记录并检查字符串是否在整个块中匹配:

awk 'BEGIN { RS = "" } /\nB:[[:space:]]+567/ { print $0 ORS }' infile

它产生:

BEGIN
A: xyz
B: 56789
C: abc
END 

BEGIN
A: ghi
B: 56712
C: pqr
END
于 2013-10-08T20:27:24.687 回答
2

这个 awk 应该可以工作:

awk -v s='B: 567' '$0~s' RS= file
BEGIN
A: xyz
B: 56789
C: abc
END
BEGIN
A: ghi
B: 56712
C: pqr
END
于 2013-10-08T20:42:00.317 回答
2

有点长,但 RS 技巧已经发布了 :-)

BEGIN {found=0;start=0;i=0}


/BEGIN/ {
    start=1
    delete a
}

/.*567.*/ {found=1}

{
    if (start==1) {
        a[i++]=$0
    }
}

/END/ {
    if (found) {
        for (i in a)
            print a[i]
    }
    found=0
    start=0
    delete a
}

输出:

$ awk -f s.awk input
BEGIN
A: xyz
B: 56789
C: abc
END
BEGIN
A: ghi
B: 56712
C: pqr
END
于 2013-10-08T20:46:52.487 回答
0
perl -lne 'if(/56789/){$f=1}
           push @a,$_;
           if(/END/){
              if($f){print join "\n",@a}
           undef @a;$f=0}' your_file
于 2013-10-09T06:46:37.930 回答