hi,
i need my bash script to find regex in xml file.. and comment 2 lines before and after the line that contains regex.. can't use # needs to be <!-- at the beginning and --> and the end of the comment.
so eg..
first block
<filter>
<filter-name>MyRegEx</filter-name>
<filter-class>MyRegExblablabla</filter-class>
</filter>
second block
<filter-mapping>
<filter-name>MyRegEx</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
so output should be
first block
<!--
<filter>
<filter-name>MyRegEx</filter-name>
<filter-class>MyRegExblablabla</filter-class>
</filter>
-->
second block
<!--
<filter-mapping>
<filter-name>MyRegEx</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
unfortunately since it's an xml file.. # is not funtioning..
obviously there is no problem to find regex.. .. i can also find the lines of regex.. the difficulty is to wrap around 2 lines before and after.. with <!-- and -->
Does anyone know how to do it? i have been working on it for quite some time now..
You want to comments out lines, try sed, using N to get the entire element in /<\([^ >]*\).<\/\1>/, and then wrap it in comment markup s/./<!-- & -->/ or similar.
Using sed N to get an entire element. Let's say the element name is MsgBlk:
sed '
/<MsgBlk[ >]/{
:loop
/<\/Msgblk>/!{
$d
N
b loop
}
s/<MsgBlk[ >].*<\/MsgBlk>/<!--\
&\
-->/
}
'
Narrative:
Find the line with the opening element, and on it:
Set a branch target named loop.
If the element is not closed:
If at EOF, it is junk, delete it. Some sed are funny wih N at EOF.
Pile the next line at the end of the buffer.
Go back to check fo close of element.
Pick up just exactly this whole element, and where its ends were, put commenting markup and new lines around the while element.
is there a way with sed to removed more than one set of lines in one line?
so i mean
sed ${firstElem},${lastIndex}d web.xml > web1.xml
this will delete lines between ${firstElem},${lastIndex}
i want in the same line to do somethinkg like this (doesn't work so far)
sed ${firstElem},${lastIndex}d ; ${secondElem},${lastIndex1}d web.xml > web1.xml
at the same time delete lines between ${firstElem},${lastIndex} and ${secondElem},${lastIndex1}d
if i don't do this in one line.. indexes for the second set change.. and i need to grep for them again.. so it would be really good if i could delete the two sets simulatiously..
thanks a lot
---------- Post updated at 06:29 PM ---------- Previous update was at 06:28 PM ----------
trying a different way.. now..
is there a way with sed to removed more than one set of lines in one line?
so i mean
sed ${firstElem},${lastIndex}d web.xml > web1.xml
this will delete lines between ${firstElem},${lastIndex}
i want in the same line to do somethinkg like this (doesn't work so far)
sed ${firstElem},${lastIndex}d ; ${secondElem},${lastIndex1}d web.xml > web1.xml
at the same time delete lines between ${firstElem},${lastIndex} and ${secondElem},${lastIndex1}d
if i don't do this in one line.. indexes for the second set change.. and i need to grep for them again.. so it would be really good if i could delete the two sets simulatiously..
Well, sed will happily delete ranges with "/regex1/,/regex2/d", and you can do that as many times as you want (as long as one does not start within another).
Your xml is pretty well behaved, but I often normalize it so every element starts at the beginning of a line. That simplified subsequent parsing, so you do not need to worry about one line elements except like <xxx yyy="zzz" www="xxx" />. You could expand that, so it is entirely simply normal.
I often pile sed on sed in a pipeline. The sort of sed that loops and does N does not mix easily with those that do simple line filtering, so why not, pipes are free. You can even embed each sed command in an executable script file that begins in the line "#!/usr/bin/sed -f" (your path may vary) and execute the scripts.
If you use regex not line #, then line numbering is not an issue. Consider doing it like "diff -e" output: put the changes in reverse line number order.
sed numbers lines at input, so the numbers do not change on one pass, in any case.