Sed: regular expression match lines without ‹!--

I have a sed command to comment out xml commands

sed 's/^\([ \t]*\)\(.*[0-9a-zA-Z<].*\)$/\1<!-- Security: \2 -->/' web.xml 

Takes:

<a>

  <!-- Comment -->
  <b>
    bla
  </b>

</a>

Produces:

<!-- Security: <a> -->

  <!-- Security: <!-- Comment --> -->    // NOTE: there are two end comments.  
  <!-- Security: <b> -->
    <!-- Security: bla -->
  <!-- Security: </b> -->

<!-- Security: </a> -->

Ideally I would like to not use my sed script to comment things that are already commented.

Ie:

<!-- Security: <a> -->

  <!-- Comment -->
  <!-- Security: <b> -->
    <!-- Security: bla -->
  <!-- Security: </b> -->

<!-- Security: </a> -->

I could do something like this:

sed 's/^\([ \t]*\)\(.*[0-9a-zA-Z<].*\)$/\1<!-- Security: \2 -->/' web.xml
sed 's/^[ \t]*<!-- Security: \(<!--.*-->\) -->/\1/' web.xml

but I think a one liner is cleaner (?)

This is pretty similar: matching a line that doesn't contain specific text with regular expressions


person sixtyfootersdude    schedule 05.04.2010    source แหล่งที่มา


คำตอบ (3)


This seems to work.

^([ \t]*)(?!<!--)([0-9a-zA-Z<].*)$

You have to escape the parenteses and other stuff in order to actually make it work with sed.

Tested the expression in an online regular expression tester.

Unfortunately it seems that sed does not support lookahead (but ssed does).
maibe you should try awk or ssed.

person João Portela    schedule 05.04.2010
comment
Yeah I have tried that (and different variations) but I could not get it to work. It ends up highlighting nothing. - person sixtyfootersdude; 05.04.2010
comment
Upon further reading it seems sed does not support those expressions. you have to use ssed and active perl mode (-R). found that info here: sed.sourceforge.net/sedfaq6.html - person João Portela; 06.04.2010
comment
คูล. That is what I thought too. +1 for clarification - person sixtyfootersdude; 06.04.2010

you can use awk, If i get your requirement correct:

awk -F"," '!/<!--/&&NF{$0="<!-- Security: "$0"-->"}1' file
person ghostdog74    schedule 06.04.2010
comment
hmmm, really would prefer to use sed but +1 for suggestion. - person sixtyfootersdude; 07.04.2010

Ended up going with this:

startInsert="<!-- Security: "
endInsert=" -->"

whiteSpace="[ \t]*"
char="[0-9a-zA-Z^_)!-/:-@[-\{-~]"

sed "s/^\($whiteSpace\)\(.*$char.*\)$/\1$startInsert\2$endInsert/" $file 
sed "s/^\($whiteSpace\)$startInsert\(<!--.*\-->\)$endInsert/\1\2/" $file 

Not as graceful as I was hoping for but works like a charm.

person sixtyfootersdude    schedule 07.04.2010