Sed: строки соответствия регулярному выражению без ‹! -

У меня есть команда sed для комментирования команд xml

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

Принимает:

<a>

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

</a>

Производит:

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

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

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

В идеале я бы не хотел использовать свой сценарий sed для комментирования уже прокомментированных вещей.

Ie:

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

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

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

Я мог бы сделать что-то вроде этого:

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

но я думаю, что один лайнер чище (?)

Это очень похоже: соответствует строке, которая не соответствует не содержат конкретный текст с регулярными выражениями


person sixtyfootersdude    schedule 05.04.2010    source источник


Ответы (3)


Кажется, это работает.

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

Вам нужно избегать парентесов и прочего, чтобы заставить его работать с sed.

Проверено выражение в интерактивном тестере регулярных выражений.

К сожалению, похоже, что sed не поддерживает просмотр вперед (но ssed поддерживает).
maibe you следует попробовать awk или ssed.

person João Portela    schedule 05.04.2010
comment
Да, я пробовал это (и разные варианты), но не смог заставить его работать. В итоге ничего не выделяется. - person sixtyfootersdude; 05.04.2010
comment
При дальнейшем чтении кажется, что sed не поддерживает эти выражения. вы должны использовать ssed и активный режим Perl (-R). нашел эту информацию здесь: sed.sourceforge.net/sedfaq6.html - person João Portela; 06.04.2010
comment
Coool. Я тоже так думал. +1 за разъяснения - person sixtyfootersdude; 06.04.2010

вы можете использовать awk, если я правильно понимаю ваше требование:

awk -F"," '!/<!--/&&NF{$0="<!-- Security: "$0"-->"}1' file
person ghostdog74    schedule 06.04.2010
comment
хммм, я бы предпочел использовать sed, но +1 для предложения. - person sixtyfootersdude; 07.04.2010

Закончил этим:

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 

Не так изящно, как я надеялся, но работает как шарм.

person sixtyfootersdude    schedule 07.04.2010