Звучит как работа для sed
(мне так хотелось сказать SuperSed; -)
sed -n '/^<.\+>/H; /\(Request\|Response\) XML/{s/^.*</</;x;p}; ${x;p}' xmllog
где xmllog
- имя вашего файла журнала. В начале вы получите пустую строку, но ее можно отфильтровать с помощью egrep '.+'
или даже tail -n +2
.
В порядке пояснения, sed
- это небольшой интерпретатор для программ, которые состоят из списка соответствующих условий и соответствующих действий. sed
пробегает файл строка за строкой (отсюда и название «редактор потока» -> «sed») и для каждой строки для каждого условия в программе, соответствующего тексту в строке, применяет соответствующее действие. В этом случае:
/^<.\+>/
- это условие регулярного выражения, которое соответствует любой строке, содержащей <
, за которой следует любой символ (.
), повторенный один или несколько раз (\+
), за которым следует >
- практически любая строка с тегом XML. Связанное действие - H
, которое добавляет строку в «буфер удержания». Другое условие
/\(Request\|Response\) XML/
, который, конечно, является регулярным выражением, которое соответствует либо Request
, либо Response
, за которым следует пробел, а затем XML
. Соответствующее действие
{s/^.*</</;x;p}
, который сначала выполняет подстановку (s
) начала строки (^
), за которым следует любой символ (.
), повторенный любое количество раз (*
), за которым следует <
, с просто <
. В основном это избавляет от чего-либо до появления первого XML-тега в строке. Затем он переключает (x
) только что прочитанную строку с помощью «буфера удержания» (который содержит XML предыдущего сообщения журнала) и печатает (p
) материал, который был только что выгружен из буфера удержания. Наконец,
$
совпадает с концом ввода, а {x;p}
снова просто заменяет содержимое буфера хранения в «буфер печати» и затем печатает его.
Вы можете изменить команду в соответствии со своими потребностями, например, если вам нужно что-то для разделения различных записей, между ними будет пустая строка:
sed -n '/^<.\+>/H; /\(Request\|Response\) XML/{s/^.*</\n</;x;p}; ${x;p}' xmllog
(в этом случае, конечно, не используйте egrep
, чтобы отфильтровать пустую строку в начале).