Полезное `sed` упражнение - PullRequest
0 голосов
/ 05 июля 2019

(Я прошу прощения за смутное название. Если у кого-то есть лучшая формулировка, пожалуйста, дайте мне знать.)

Мой вопрос касается функции, которую я хочу реализовать с помощью sed, которая появлялась снова и снова. В настоящее время у меня есть решение, но оно некрасиво и разрушает какой-то формат. Я опишу их ниже.

Вопрос

Обычно я должен обработать файл, подобный этому

.
.
<pattern A>
.
.
<pattern B>
.. <pattern B1>
..
.. <pattern B2>
..
.. <pattern B3>
<pattern B>
.
.
<pattern A>
<pattern B>
.
.

Я обычно нахожу, что я хотел бы сосредоточиться на каждой вещи между или вне <pattern A>, или сосредоточиться на

<pattern B>
.. <pattern B1>
..
.. <pattern B2>
..
.. <pattern B3>
<pattern B>

, игнорируя определенные <pattern B> во всем файле.

Есть ли какой-нибудь элегантный способ сделать это с sed?

Конкретный пример

1

Из файла

<html>
<div>
1st div
</div>
<div>
2nd div
</div>
..

<div>
10th div
</div>
</html>

как извлечь

<div>
3rd div
.
.
7th div
</div>

2

Из файла

<html>
.
.
<ol> # the first <ol> in the whole file
.
.
</ol> # the last </ol> in the whole file
.

Как извлечь

<ol> # the first <ol> in the whole file
.
.
</ol> # the last </ol> in the whole file

Что я пробовал

Мое текущее решение очень уродливо и ненадежно. Я просто удаляю все новые строки, делая весь файл однострочным, и делаю много уродливого sed -магического ... К счастью, в моем случае я обычно могу вводить новые строки назад ... но это определенно не правильный путь.

Пожалуйста, дайте мне знать, если необходимо предоставить дополнительную информацию. Я знаю, что это как-то расплывчатый вопрос, но это именно то, чего я хочу .. Может ли sed обнаружить шаблоны во всем файле, как этот? Я заранее ценю вашу помощь!

1 Ответ

1 голос
/ 05 июля 2019

Это может сработать для вас (GNU sed):

sed -nE '/<div>/{H;:a;n;H;/<\/div>/!ba;x;s/^/x/;/^x{3,7}\n/{H;s/^[^\n]*\n//p;g;s///;s/\n.*//;x;s///;b};s/\n.*//;x}' file

В этом файле печатаются только с 3 по 7 div с. Он использует первую строку пространства удержания в качестве счетчика, и каждый раз, когда он встречает div в файле, добавляет его в пространство удержания, увеличивает счетчик и решает, печатать или не печатать подарок div. Тот же механизм можно использовать для печати всех div с, используя:

sed -nE '/<div>/{H;:a;n;H;/<\/div>/!ba;x;s/^/x/;/^x{1,}\n/{H;s/^[^\n]*\n//p;g;s///;s/\n.*//;x;s///;b};s/\n.*//;x}' file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...