Reputation: 137
I have pre-generated configuration files from a utility. How can I extract the parameter string which is delimited by '),
that may or may not span multiple lines?
FILE1
can look like this - PARM3
spans multiple lines:
OPERAND ID = 'XXXX',
....
PARM3 = ( 'VALUE3A',
....
'VALUE3n'),
PARM4 = ( 'VALUE4',
....
'VALUE4n'),
....
or FILE2
can look like this - PARM3
does not span multiple lines:
OPERAND ID = 'XXXX',
....
PARM3 = ( 'VALUE3A'),
PARM4 = ( 'VALUE4',
....
'VALUE4n'),
....
For FILE1
, the extract is good if the delimiter '),
is on another line:
sed -n "/.* PARM3 .*/,/')\,/p" FILE1
Output:
PARM3 = ( 'VALUE3A',
....
'VALUE3n'),
For FILE2
, the extract does not work if the delimiter '),
is on the same line:
sed -n "/.* PARM3 .*/,/')\,/p" FILE2
Output:
PARM3 = ( 'VALUE3A'),
PARM4 = ( 'VALUE4',
....
'VALUE4n'),
How can I fix this sed statement using sed only to handle the delimiter which may or may not be on the same line?
Upvotes: 1
Views: 56
Reputation: 785651
You may use this gnu-awk
command that uses a custom RS
:
awk -v RS='[[:blank:]]*PARM3[[:blank:]]*=[[:blank:]]*\\([^)]*\\),[[:blank:]]*' 'RT{print RT}' file
For file1 it gives:
PARM3 = ( 'VALUE3A',
....
'VALUE3n'),
For file2 it gives:
PARM3 = ( 'VALUE3A'),
Upvotes: 1
Reputation: 89584
[EDIT]more simple:
sed -n '/PARM3/,/)/{p;/)/q}' file
a way with sed:
sed -n '/PARM3/{:a;/)/{p;q};N;ba}' file
details:
/PARM3/ { # if PARM3 is found
:a # define a label "a"
/)/ { # if ) is found
p # print the pattern space
q # quit
}
N # append the next line to the pattern space
ba # go to label a
}
Upvotes: 1
Reputation: 52381
If you have GNU grep, you could use its -z
option to treat the complete input as a single line:
$ grep -Ezo '\s+PARM3\s+=\s+\([^)]*\)' FILE2
PARM3 = ( 'VALUE3A',
....
'VALUE3n')
-o
retains nothing but the match, and -E
enables extended regular expressions.
The regex searches for PARM3 =
surrounded by an arbitrary number of blanks, followed by (
and then everything up to and including the closing )
. To avoid greedy matching, I use [^)]
("not a closing parenthesis").
If you don't need the leading blanks, they can be skipped, and if you need the trailing comma, it can be added (optional, in case it's not there):
$ grep -Ezo 'PARM3\s+=\s+\([^)]*\),?' infile
PARM3 = ( 'VALUE3A',
....
'VALUE3n'),
or to get proper alignment, but not the newline preceding the match:
$ grep -Ezo '[[:blank:]]*PARM3\s+=\s+\([^)]*\),?' infile
PARM3 = ( 'VALUE3A',
....
'VALUE3n'),
Upvotes: 0