Я думаю, что на самом деле я бы это сделал с gawk, а не с sed.
Вы не указали входные данные, поэтому я сделаю некоторые из них.
$ printf '<a><b></b><b></b></a><a><c></c></a>' | gawk -vRS='</a>' '{print $0 RS}'
<a><b></b><b></b></a>
<a><c></c></a>
Как правило, AWK (или простак) рассмотрит каждую строку быть уникальной записью, с каждой линией разделяется на поля, разделенных пробелами.
Если вы разделили записи каким-либо XML-тегом, вы можете положиться на то, что после печати каждой «входной записи» print
добавит новую строку как разделитель выходной записи по умолчанию.
В отличие от решения sed, которое попытается прочитать одну целую «запись» (строку) в память для выполнения действий над ней, я подозреваю, что это решение будет проходить через ваш файл, только используя достаточное количество памяти для «запоминания» пространство между разделителями записей. (Это относится к проблеме «большого файла».)
Три других примечания.
Во-первых, разделитель записей НЕ является понятием, родным для XML, поэтому любое решение с использованием sed, awk или всего, что не интерпретирует XML XML , является взломом. Вы всегда будете получать лучшие результаты, используя инструменты, которые поддерживают ваш формат данных.
Во-вторых, поскольку в моем примере я определил разделитель записей, который является закрытием тега XML, входные данные могут быть, хотя и иметь ТРИ ЗАПИСИ, третий из которых является нулевым. Если у вас есть новая строка после окончательного «разделителя записей», эта третья запись может быть завершена еще одним RS в вашем выводе. Имейте в виду. Это результат вещи №1.
В-третьих, это простак решение, не AWK решение, потому что другие реализации, как правило, не поддерживают несколько символов в качестве разделителей записей.
YMMV. Это не отличное решение, но этого может быть достаточно для ваших нужд.
Спасибо @ghoti, это решение было самым быстрым, что делало то, что я хотел. – bhowmik