Reputation: 53
I have a config file:
config line 1
....
config line n
router mk1
ip 10.1.1.2
deviceType t1
sub config line!
sub config line 2
!more sub config
!
!!!
more config lines
router mk2
ip 10.1.1.2
sub config line1
sub config line 2
deviceType t2
!
Each router block starts with the word router on a new line and ends with ! on a new line. A config file can contain many router blocks.Each sub-block begins with a single space.The lines in sub-block can be in any order.I want to select a block that contains a specific line for eg: deviceType t2.
So far I could identify all the router blocks with the following:
(?ms)^router mk.*?^!$
But I only need a block that contains the line deviceType t2
Upvotes: 0
Views: 208
Reputation: 110695
The following regular expression should work for most all regex engines (though it may be necessary to replace \R
with \r?\n
). I tested it with the PCRE (PHP) regex engine.
(?m)^router .+\R(?: .*\R)* deviceType t2\R(?: .*\R)*!$
The engine performs the following operations.
(?m) : multiline mode (^ and $ match beginning and end of line)
^ : match start of line
router .*\R : match line beginning 'router ', including terminator
(?: .*\R)* : match a line including terminator that begins with a
space in a non-capture group, execute 0+ times
deviceType t2\R : match line 'deviceType t2', including terminator
(?: .*\R)* : match a line including terminator that begins with a
space in a non-capture group, execute 0+ times
!$ : match the line '!'
Upvotes: 1
Reputation:
don't wurry boute line endings, most engines have multi-line mode
try (?m)^router.*\s*(?:^(?!!).*\s*)*?^\s*deviceType\s+t2.*\s*(?:^.*\s*)*?^!
uses fewest steps, yes ?
Upvotes: 1
Reputation: 627022
You may use
(?m)^router mk\d+(?:\R(?!router mk\d+$).*)*?\R\s*deviceType t2(?:\R.*)*?\R!$
(?m)^router mk\d+(?:\n(?!router mk\d+$).*)*?\n\s*deviceType t2(?:\n.*)*?\n!$
(?m)^router mk\d+(?:\r?\n(?!router mk\d+$).*)*?\r?\n\s*deviceType t2(?:\r?\n.*)*?\r?\n!$
See the regex demo. The variations are for different kinds of line break sequences, \R
matches any line break, \n
only matches LF line endings, and \r?\n
matches CRLF or LF line endings.
Details
(?m)
- MULTILINE mode on^
- line start router mk\d+
- router mk
and 1+ digits(?:\R(?!router mk\d+$).*)*?
- 0 or more occurrences, but as few as possible, of the following sequence of patterns:
\R(?!router mk\d+$)
- a line break sequence not followed with router mk
+ one or more digits at the end of a line.*
- any 0 or more chars other than line break chars, as many as possible\R\s*
- a line break sequence and then 0+ whitespacesdeviceType t2
- a literal string(?:\R.*)*?
\R
- line break sequence !
- !
$
- end of line.Upvotes: 1