Заменить начало каждой строки возможно многострочного шаблона - PullRequest
1 голос
/ 02 апреля 2019

Я пытаюсь сопоставить многострочный шаблон и изменить каждую строку, соответствующую этому шаблону, включая первую, чтобы в начале строки был добавлен символ (+/-)

Например, у меня есть это:

stuff above
<span>one-liner span</span>
stuff middle
    <span>stuff inside
    other stuff
    </span>
stuff below

И я хочу получить это:

stuff above
+ <span>one-liner span</span>
stuff middle
+     <span>stuff inside
+     other stuff
+     </span>
stuff below

Пока я там:

perl -n0e 's/\n(.*<span style="color: green".*?<\/span>)/+$1/g && print' myfile.html

Проблема здесь в том, что он изменяет только первую строку, и если это многострочный шаблон, я хочу изменить все строки.

Есть идеи, как это сделать?

Я использую Perl, но я открыт для других инструментов, если вы считаете, что это лучше.

Спасибо!

Ответы [ 3 ]

2 голосов
/ 02 апреля 2019

Одним из способов является использование оператора диапазона

perl -wpe'print "+ " if /^\s*<span/ .. /<\/span>/' file

Оператор .. в этом использовании поддерживает свое состояние, так что

Как только левый операнд равен true, оператор диапазона остается истинным, пока правый операнд не станет true, ПОСЛЕ того, как оператор диапазона снова станет ложным.

Его типичное использование - точный выбор диапазона линий, ограниченных данными условиями.

Здесь я ограничил открытие span s первой непустой вещью в своей строке, но не закрывающей, чтобы разрешить работу однострочных <span ...>word</span> секций.

1 голос
/ 02 апреля 2019

Используйте оператор диапазона, чтобы замаскировать нужный диапазон, а затем добавьте строки, начинающиеся с пробела. Этот код не дает именно то, что вы хотите, но укажет вам правильное направление.

while(<>) {
    if( /stuff above/ .. /stuff below/ ){
        $_= "+".$_ if /^ +/;
        print $_;
    }
}

Оператор дальности - один из моих любимых!

0 голосов
/ 10 апреля 2019

если ваши данные в файле 'd'

perl -ne 'if (/^\s*<(span)>.*?(<\/\1>)?\s*$/) {print "+$&";next if ($2);$t="</$1>";do{$_=<>;print "+$_"} until(/$t/) } else {print}' d

GNU SED

sed -E 's/<(span)>.*<\/\1>/+&/;Tc;b ;:c /^\s*<span>/{s/^/+/;:l n;s/^/+/;/<\/span>/!bl}' d
...