Intereting Posts

Совпадение любого символа (включая символы новой строки) в sed

У меня есть команда sed, которую я хочу запустить на огромном, ужасном, уродливом HTML-файле, который был создан из документа Microsoft Word. Все, что он должен сделать, это удалить любой экземпляр строки

style='text-align:center; color:blue; exampleStyle:exampleValue' 

Команда sed, которую я пытаюсь изменить,

 sed "s/ style='[^']*'//" fileA > fileB 

Он отлично работает, за исключением того, что всякий раз, когда в соответствующем тексте есть новая строка, она не совпадает. Есть ли модификатор для sed или что-то, что я могу сделать, чтобы принудительно выполнить сопоставление любого персонажа, включая символы новой строки?

Я понимаю, что регулярные выражения ужасны в XML и HTML, blah blah blah, но в этом случае строковые шаблоны хорошо сформированы в том, что атрибуты стиля всегда начинаются с одной кавычки и заканчиваются одной цитатой. Поэтому, если бы я мог просто решить проблему новой строки, я мог бы сократить размер HTML более чем на 50% только одной командой.


В конце концов выяснилось, что сценарий Perl Sinan Ünür работал лучше всего. Это было почти мгновенно, и это уменьшило размер файла от 2,3 МБ до 850 тыс. Хороший ol ‘Perl …

sed входной файл по строке, что означает, как я понимаю, то, чего вы хотите, невозможно в sed .

Вы можете использовать следующий скрипт Perl ( непроверенный ), хотя:

 #!/usr/bin/perl use strict; use warnings; { local $/; # slurp mode my $html = <>; $html =~ s/ style='[^']*'//g; print $html; } __END__ 

Один лайнер был бы:

 $ perl -e 'local $/; $_ = <>; s/ style=\047[^\047]*\047//g; print' fileA > fileB 

Сед читает ввод строки за строкой, поэтому не просто обрабатывать одну строку … но это тоже не невозможно, вам нужно использовать ветвление sed. Следующее будет работать, я прокомментировал это, чтобы объяснить, что происходит (не самый читаемый синтаксис!):

 sed "# if the line matches 'style='', then branch to label, # otherwise process next line /style='/b style b # the line contains 'style', try to do a replace : style s/ style='[^']*'// # if the replace worked, then process next line t # otherwise append the next line to the pattern space and try again. N b style " fileA > fileB 

Вы можете удалить все CR / LF, используя tr , запустить sed , а затем импортировать в редактор, который автоматически форматируется.

Другой способ:

 $ cat toreplace.txt I want to make \ this into one line I also want to \ merge this line $ sed -e 'N;N;s/\\\n//g;P;D;' toreplace.txt 

Вывод:

 I want to make this into one line I also want to merge this line 

N загружает другую строку, P печатает пространство шаблонов до первой новой строки, а D удаляет пространство шаблонов до первой новой строки.

Вы можете попробовать следующее:

 awk '/style/&&/exampleValue/{ gsub(/style.*exampleValue\047/,"") } /style/&&!/exampleValue/{ gsub(/style.* /,"") f=1 } f &&/exampleValue/{ gsub(/.*exampleValue\047 /,"") f=0 } 1 ' file 

Вывод:

 # more file this is a line style='text-align:center; color:blue; exampleStyle:exampleValue' this is a line blah blah style='text-align:center; color:blue; exampleStyle:exampleValue' blah blah.... # ./test.sh this is a line this is a line blah blah blah blah....