How to extract entire para instead of just line?

Hello,

I have a file with multiple paragraphs/sections each starting with word "Handle" and if I grep for a pattern, I should get contents of entire section/para (not just line). Please advise, thanks!

#script.sh file.txt "System Information"
Handle 0x0001
        DMI type 1, 27 bytes.
        System Information
                Manufacturer: VMware, Inc.
                Product Name: VMware Virtual Platform
                Version: None
                Serial Number: VMware-50 2a 97 c6 3e 64 b4 f5-ec 9f 59 78 f3 5d                                                                                         13 6a
                UUID: 502A97C6-3E64-B4F5-EC9F-5978F35D136A
                Wake-up Type: Power Switch
#cat file.txt
SMBIOS 2.4 present.
98 structures occupying 3681 bytes.
Table at 0x000E0010.
Handle 0x0000
        DMI type 0, 24 bytes.
        BIOS Information
                Vendor: Phoenix Technologies LTD
                Version: 6.00
                Release Date: 04/15/2011
                Address: 0xEA2E0
                Runtime Size: 89376 bytes
                ROM Size: 64 kB
                Characteristics:
                        ISA is supported
                        PCI is supported
                        PC Card (PCMCIA) is supported
                        PNP is supported
                        APM is supported
                        BIOS is upgradeable
                        BIOS shadowing is allowed
                        ESCD support is available
                        USB legacy is supported
                        Smart battery is supported
                        BIOS boot specification is supported
Handle 0x0001
        DMI type 1, 27 bytes.
        System Information
                Manufacturer: VMware, Inc.
                Product Name: VMware Virtual Platform
                Version: None
                Serial Number: VMware-50 2a 97 c6 3e 64 b4 f5-ec 9f 59 78 f3 5d                                                                                         13 6a
                UUID: 502A97C6-3E64-B4F5-EC9F-5978F35D136A
                Wake-up Type: Power Switch
Handle 0x0002
        DMI type 2, 15 bytes.
        Base Board Information
                Manufacturer: Intel Corporation
                Product Name: 440BX Desktop Reference Platform
                Version: None
                Serial Number: None
                Asset Tag: Not Specified
                Features: None
                Location In Chassis: Not Specified
                Chassis Handle: 0x0000
                Type: Unknown
                Contained Object Handlers: 0
Handle 0x0003
        DMI type 3, 21 bytes.
        Chassis Information
                Manufacturer: No Enclosure
                Type: Other
                Lock: Not Present
                Version: N/A
                Serial Number: None
                Asset Tag: No Asset Tag
                Boot-up State: Safe
                Power Supply State: Safe
                Thermal State: Safe
                Security Status: None
                OEM Information: 0x00001234
Heigth: Unspecified
Number Of Power Cords: Unspecified
                Contained Elements: 0

An awk approach:

awk -v S="System Information" '
        {
                if ( $0 !~ /^ / )
                        T = $0
                if ( T )
                        A[T] = A[T] ? A[T] RS $0 : $0
        }
        END {
                for ( k in A )
                {
                        if ( A[k] ~ S )
                                print A[k]
        }       }
' file.txt

Is this dmidecode output? Try:

dmidecode | awk '/System Information/' RS=

or try:

dmidecode -qt 0x0001

or

dmidecode -s system-manufacturer

etc..

Thanks Yoda and Scrutinizer.

@Yoda - Sorry your solution NOT working. It just prints System Information

# awk -v S="System Information" '
        {
                if ( $0 !~ /^ / )
                        T = $0
                if ( T )
                        A[T] = A[T] ? A[T] RS $0 : $0
        }
        END {
                for ( k in A )
                {
                        if ( A[k] ~ S )
                                print A[k]
        }       }
' /tmp/dmi_out
        System Information

@Scrutinzer - You are right. Actually I need to run dmidecode -t system which does NOT work on older RHEL 3 & 4 [ It works on RHEL 5.3 onwards ]. Hence Am trying to run just dmidecode and extract only the paragraph with "System Information".

-qt and -s options are also not working.

Please advise - thanks a lot!!

$ sed 's/^[^[:space:]]/^&/' dmi.out | awk '/System Info/' RS=^
Handle 0x0001
        DMI type 1, 27 bytes.
        System Information
                Manufacturer: VMware, Inc.
                Product Name: VMware Virtual Platform
                Version: None
                Serial Number: VMware-50 2a 97 c6 3e 64 b4 f5-ec 9f 59 78 f3 5d
        13 6a
                UUID: 502A97C6-3E64-B4F5-EC9F-5978F35D136A
                Wake-up Type: Power Switch

I spent a little while trying to get (GNU) awk to use a record separator of 'any line which doesn't start with a space', but failed.

Try not so good...

$ awk '/System Information/{print;while(getline){if(!/^[ \t]+/){exit}print}}' dmi.out
        System Information
                Manufacturer: VMware, Inc.
                Product Name: VMware Virtual Platform
                Version: None
                Serial Number: VMware-50 2a 97 c6 3e 64 b4 f5-ec 9f 59 78 f3 5d                                                                                         13 6a
                UUID: 502A97C6-3E64-B4F5-EC9F-5978F35D136A
                Wake-up Type: Power Switch

Put the below code in script.sh

awk '/^Handle/ {print ""}1' "${1}" | awk '$0 ~ pat' pat="${2}" RS=

and run the script as below

./script.sh file.txt "System Information"

output:

$ ./script.sh file.txt "System Information"
Handle 0x0001
        DMI type 1, 27 bytes.
        System Information
                Manufacturer: VMware, Inc.
                Product Name: VMware Virtual Platform
                Version: None
                Serial Number: VMware-50 2a 97 c6 3e 64 b4 f5-ec 9f 59 78 f3 5d                                                                                         13 6a
                UUID: 502A97C6-3E64-B4F5-EC9F-5978F35D136A
                Wake-up Type: Power Switch
$

Try:

awk '!/^ /{if(f)exit; p=x} /System Information/{f=1} {p=p $0 ORS} END{if(f)print p}' file

or

awk '!/^ /{if(f)exit; p=x} $0~s{f=1} {p=p $0 ORS} END{if(f)print p}' s="System Information" file

Another approach
Paste the below code in your script.sh

awk '/^Handle/ {if(p ~ pat) print p; p=$0; next} {p = p "\n" $0} END {if(p ~ pat) print p}' pat="${2}" "${1}"

Hi.

Command cgrep allows this kind of extraction, for example:

#!/usr/bin/env bash

# @(#) s1	Demonstrate "paragraph" extraction, dmidecode output, cgrep
# For cgrep source, see:
# http://sourceforge.net/projects/cgrep/

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C

FILE=${1-data1}
lines=$( wc -l < $FILE )

pl " Part of input data file $FILE, $lines total lines:"
head $FILE

pl " Expected output:"
cat expected-output.txt

pl " Results:"
cgrep -D +w "^Handle" -w "^Handle" +I2 "System Information" $FILE

exit 0

producing:

./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution        : Debian 5.0.8 (lenny, workstation) 
bash GNU bash 3.2.39
cgrep ATT cgrep 8.15

-----
 Part of input data file data1, 63 total lines:
SMBIOS 2.4 present.
98 structures occupying 3681 bytes.
Table at 0x000E0010.
Handle 0x0000
        DMI type 0, 24 bytes.
        BIOS Information
                Vendor: Phoenix Technologies LTD
                Version: 6.00
                Release Date: 04/15/2011
                Address: 0xEA2E0

-----
 Expected output:
Handle 0x0001
        DMI type 1, 27 bytes.
        System Information
                Manufacturer: VMware, Inc.
                Product Name: VMware Virtual Platform
                Version: None
                Serial Number: VMware-50 2a 97 c6 3e 64 b4 f5-ec 9f 59 78 f3 5d                                                                                         13 6a
                UUID: 502A97C6-3E64-B4F5-EC9F-5978F35D136A
                Wake-up Type: Power Switch

-----
 Results:
Handle 0x0001
        DMI type 1, 27 bytes.
        System Information
                Manufacturer: VMware, Inc.
                Product Name: VMware Virtual Platform
                Version: None
                Serial Number: VMware-50 2a 97 c6 3e 64 b4 f5-ec 9f 59 78 f3 5d                                                                                         13 6a
                UUID: 502A97C6-3E64-B4F5-EC9F-5978F35D136A
                Wake-up Type: Power Switch

The cgrep command needs to be compiled. See the comment in the script for location.

Best wishes ... cheers, drl