Hi All,
I'm appending a line before a pattern and after another pattern( but omitting the first pattern - same as if comes duplicates before the second pattern.
Also, I'm adding a word before the first pattern -
Here is my file
select blah blah
hello
select blah blah
;
select blah blah
hi
select blah blah
;
My expectation would be -
\o | grep org
anyword select blah blah
hello
select blah blah
;
\o
\o | grep org
anyword select blah blah
hi
select blah blah
;
\o
Here is my sed command I'm using with my file-
sed -e '/^ *[sS][eE][lL][eE][cC][tT]/ i \\\o | grep org' testfilepr.txt | sed -e 's/\(^ *[sS][eE][lL][eE][cC][tT]\)/anyword \1/g' | sed -e ' s/;/;\n\\\o/'
But my output comes out to be -
\o | grep org
anyword select blah blah
hello
\o | grep org
anyword select blah blah
;
\o
\o | grep org
anyword select blah blah
hi
\o | grep org
anyword select blah blah
;
\o
Please suggest.
A sed multi-liner
sed '/^ *[sS][eE][lL][eE][cC][tT]/{
i\
\\o grep org
s/^ */anyword /
:L
$!N
/;/!bL
a\
\\o
}
'
The loop appends the following lines until the end marker ;
so there are no further insertions.
1 Like
Thanks MadeInGermany!! Your code is working for me in mentioned scenarios.
Could you please help out if we have some data like -
(
select blah blah
hello
select blah blah
;
select blah blah
hi
select blah blah
;
or
(select blah blah
hello
select blah blah
;
select blah blah
hi
select blah blah
;
In such cases, expectation would be -
\o | grep org
(
anyword select blah blah
hello
select blah blah
;
\o
\o | grep org
anyword select blah blah
hi
select blah blah
;
\o
or
\o | grep org
(anyword select blah blah
hello
select blah blah
;
\o
\o | grep org
anyword select blah blah
hi
select blah blah
;
\o
This one tolerates one or more (
on two lines before the select
sed '
/^ *(/N
/^\( *(* *\n* *(* *\)\([sS][eE][lL][eE][cC][tT]\)/{
s//\\o | grep org\
\1anyword \2/
:L
$!N
/;/!bL
a\
\\o
}
'
I am using the s
(substitute) command for both insertions, because it can use the \( \)
back references in the previous / /
.
madeingermany:
This one tolerates one or more (
on two lines before the select
sed '
/^ *(/N
/^\( *(* *\n* *(* *\)\([sS][eE][lL][eE][cC][tT]\)/{
s//\\o | grep org\
\1anyword \2/
:L
$!N
/;/!bL
a\
\\o
}
'
I am using the s
(substitute) command for both insertions, because it can use the \( \)
back references in the previous / /
.
If I'm using below pattern, it will error out.
sed '
/^ *(/N
/^\( *(* *\n* *(* *\)\([sS][eE][lL][eE][cC][tT]\)/{
s//\\\o | grep \x27Send\\|Recv\\|Execute on\x27 | sed -e \x27s/^[ \\t]*//g\x27 -e \x27s/[|]*//g\x27 -e \x27s/[ \\t]*//g\x27 | cut -d\x27"\x27 -f2 | cut -d: -f1,2 | cut -d\\\\ -f1,2\
\1explain \2/
:L
$!N
/;/!bL
a\
\\o
}' filename.txt
The sed uses s /search/replace/
i.e. /
delimiters, so there may not be a /
in the search and replace strings.
Use another delimiter, e.g. #
:
sed '
/^ *(/N
/^\( *(* *\n* *(* *\)\([sS][eE][lL][eE][cC][tT]\)/{
s##\\o | grep org\
\1anyword \2#
:L
$!N
/;/!bL
a\
\\o
}
' filename.txt
If required, this is also possible for the /search/
, but the start delimiter needs to be escaped:
sed '
\#^ *(#N
\#^\( *(* *\n* *(* *\)\([sS][eE][lL][eE][cC][tT]\)#{
...
This is a a "sed" thread, but for comparison sake, if there are always empty lines between pattern groups then an awk version could look like this:
awk '
tolower($0)~/^\(?\n?select/ && $NF==";" {
$0="\\o | grep org\n" $0 "\n\\o"
}
print
' RS= ORS='\n\n' file
--