How can find a specific number in a text block and print the complete text block beginning with the key word \"BEGIN\"
and ending with \"
$ 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
Note the \n
before B
to ensure it occurs at the start of a line.This is in place of the ^
start-of-string character you had originally since now each line isn't it's own string. You need to set ORS above to re-insert the blank line between records.
This awk should work:
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
A bit lenghty but the RS-trick was already posted :-)
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
}
Output:
$ awk -f s.awk input
BEGIN
A: xyz
B: 56789
C: abc
END
BEGIN
A: ghi
B: 56712
C: pqr
END
This might work for you (GNU sed):
sed -n '/^BEGIN/{x;d};H;/^END/{x;s/^B: 567/&/mp}' file
or this:
sed -n '/^BEGIN/!b;:a;$!{N;/\nEND/!ba};/\nB: 567/p' file
perl -lne 'if(/56789/){$f=1}
push @a,$_;
if(/END/){
if($f){print join "\n",@a}
undef @a;$f=0}' your_file
You can undef RS
to split records in blank lines and check if the string matches in the whole block:
awk 'BEGIN { RS = "" } /\nB:[[:space:]]+567/ { print $0 ORS }' infile
It yields:
BEGIN
A: xyz
B: 56789
C: abc
END
BEGIN
A: ghi
B: 56712
C: pqr
END