Given line separated blocks of text, how can I return each block which contains a specific keyword?

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.

Answers


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.)

How it works
  • -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).


Need Your Help

How to get the Enum Index value in C#

c# c enums integer

In C, enums, internally equates to an integer. Therefore we can treat data types of enum as integer also.

Spring Data, Hibernate 4.1.1 and Spring JTA Transaction Manager

java spring hibernate jta spring-data

I am in the process of developing a web application and decided that using spring-data would be a good idea. To be fair it makes life extremely easy and the DAO layer very thin.