Reputation: 93
me$ cat file.txt
Filename: 1
Organization: Bus 1 => Port 1 => Subport 1 => Device 3
Classes: Interface Video
Drivers: usbhid
Filename: 2
Organization: Bus 1 => Port 1 => Subport 3 => Device 4
Classes: Audio
Drivers: usb-audio uvc Video
Filename: 3
Organization: Bus 1 => Port 1 => Subport 4 => Device 5
Classes: Wireless Video
Drivers: uvc
How can I manipulate this to return the blocks which contain any given keyword?
For example: bash this --class "Video" would return:
Filename: 1
Organization: Bus 1 => Port 1 => Subport 1 => Device 3
Classes: Interface Video
Drivers: usbhid
Filename: 3
Organization: Bus 1 => Port 1 => Subport 4 => Device 5
Classes: Wireless Video
Drivers: uvc
Writing the script to sort the --class and --driver case would be trivial, just asking particularly about the text manipulation. I'm thinking along the lines of grep Class:*$input, taking the line number, and printing everything from a a newline prior to that through the next newline, but that would have more complications and probably isn't the most efficient way to do it.
Upvotes: 1
Views: 96
Reputation: 113924
To get Classes...Video:
$ awk -v RS= '/Classes:[^\n]*Video/' file.txt
Filename: 1
Organization: Bus 1 => Port 1 => Subport 1 => Device 3
Classes: Interface Video
Drivers: usbhid
Filename: 3
Organization: Bus 1 => Port 1 => Subport 4 => Device 5
Classes: Wireless Video
Drivers: uvc
(I tested this with mawk and GNU awk and it should work with any POSIX awk [hat tip: ninjalj) but it may not be compatible with very old versions of awk.)
-v RS=
This sets the record separator to be an empty string which is generally interpreted as meaning paragraphs.
/Classes:[^\n]*Video/
This returns true if the record (paragraph) contains Classes:
, followed by any number of any characters except newline, followed by Video
. In other words, it returns true if a line contains the string Classes:
and later contains the string Video
. If this condition returns true, then awk performs the default action which is to print the record (paragraph).
Upvotes: 1