user2161443
user2161443

Reputation: 21

Search for a particular multiline pattern using awk and sed

I want to read from the file /etc/lvm/lvm.conf and check for the below pattern that could span across multiple lines.

tags {
 hosttags = 1
} 

There could be as many white spaces between tags and {, { and hosttags and so forth. Also { could follow tags on the next line instead of being on the same line with it.

I'm planning to use awk and sed to do this.

While reading the file lvm.conf, it should skip empty lines and comments.

That I'm doing using.

data=$(awk < cat `cat /etc/lvm/lvm.conf`            
/^#/        { next }                       
/^[[:space:]]*#/            { next }                
/^[[:space:]]*$/            { next }                
.          
.                            

How can I use sed to find the pattern I described above?

Upvotes: 2

Views: 1255

Answers (3)

Fredrik Pihl
Fredrik Pihl

Reputation: 45670

Are you looking for something like this

sed -n '/{/,/}/p' input

i.e. print lines between tokens (inclusive)?

To delete lines containing # and empty lines or lines containing only whitespace, use

sed -n '/{/,/}/p' input | sed '/#/d' | sed '/^[  ]*$/d'

                              space and a tab--^

update

If empty lines are just empty lines (no ws), the above can be shortened to

sed -e '/#/d' -e '/^$/d' input

update2

To check if the pattern tags {... is present in file, use

$ tr -d '\n' < input | grep -o 'tags\s*{[^}]*}'
tags { hosttags = 1# this is a comment}

The tr part above removes all newlines, i.e. makes everything into one single line (will work great if the file isn't to large) and then search for the tags pattern and outputs all matches.

The return code from grep will be 0 is pattern was found, 1 if not. Return code is stored in variable $?. Or pipe the above to wc -l to get the number of matches found.

update3

regex for searcing for tags { hosttags=1 } with any number of ws anywhere

'tags\s*{\s*hosttags\s*=\s*1*[^}]*}'

Upvotes: 1

Scrutinizer
Scrutinizer

Reputation: 9946

One could try preprocessing the file first, removing commments and empty lines and introducing empty lines behind the closing curly brace for easy processing with the second awk.

awk 'NF && $1!~/^#/{print; if(/}/) print x}' file | awk '/pattern/' RS=

Upvotes: 0

Kent
Kent

Reputation: 195269

try this line:

 awk '/^\s*#|^\s*$/{next}1' /etc/lvm/lvm.conf

Upvotes: 0

Related Questions