Как при помощи bash команд распарсить xml файл с логами и найти конкретные логи по заданным параметрам?
Файл с логами содержит следующую структуру:
[24/11/11 09:49:57:538 EST] DEBUG
<?xml version="1.1" encoding="UTF-8" ?>
<Request session="asdfadfasas3432423ewd3da" id=23243>
<type>Balance</type>
</Request>
[24/11/11 10:50:57:538 EST] DEBUG
<?xml version="1.1" encoding="UTF-8" ?>
<Request session="assasddsasd3r3r3r34r" id=dr5453>
<type>Withdrawal</type>
</Request>
[24/11/11 11:51:57:676 EST] DEBUG
<?xml version="1.1" encoding="UTF-8" ?>
<Request session="sadsdasdasdas3332ed3xew" id=frre54>
<type>Balance</type>
</Request>
[24/11/11 12:52:57:345 EST] DEBUG
<?xml version="1.1" encoding="UTF-8" ?>
<Request session="sdsdfsdfldsfdsfsdfdsfsd" id=0596095>
<type>Balance</type>
</Request>
Необходимо при помощи bash команд вытащить следующую информацию:
- запросы и ответы в рамках сессии asdfadfasas3432423ewd3da
- запросы и ответы в рамках сессии asdfadfasas3432423ewd3da и типом Balance
- ответы с типом Withdrawal и code отличным от 0000
- список типов операций и их количество (пример: Withdrawal: 3).
Никогда не работал с текстовыми постпроцессорами, а задачу нужно решить очень срочно.
Ответы (1 шт):
xq
Для поиска по xml подходит xq. Ставится просто:
pip install xq
Поиск
Поиск осуществляется с помощью XPath. Я взял для примера session="assasddsasd3r3r3r34r" и валидный XML файл:
<?xml version="1.0" encoding="UTF-8" ?>
<Requests>
<Request session="asdfadfasas3432423ewd3da" id="23243">
<type>Balance</type>
</Request>
<Request session="assasddsasd3r3r3r34r" id="dr5453">
<type>Withdrawal</type>
</Request>
<Request session="sadsdasdasdas3332ed3xew" id="frre54">
<type>Balance</type>
</Request>
<Request session="sdsdfsdfldsfdsfsdfdsfsd" id="0596095">
<type>Balance</type>
</Request>
</Requests>
Команда для поиска:
xq '//Requests/Request[@session="assasddsasd3r3r3r34r"]' /tmp/valid.xml
Результат:
<results>
<result>
<Request session="assasddsasd3r3r3r34r" id="dr5453">
<type>Withdrawal</type>
</Request>
</result>
</results>
Еще один вариант поиска:
xq '//Requests/Request[@session="asdfadfasas3432423ewd3da" and type="Balance"]' /tmp/valid.xml
Проверить валидность можно так:
# Установка xmllint:
sudo apt -y install libxml2-utils
# Валидация:
xmllint /tmp/valid.xml
Преобразование в валидный XML
То что у вас пишется в журнал - совершенно не XML, поэтому его нужно почистить.
grep -vP 'DEBUG|version="1.1"' /tmp/invalid.xml | \
sed '1i <?xml version="1.0" encoding="UTF-8" ?>\n<Requests>' | \
sed '$a </Requests>' > /tmp/semi-valid.xml
Тут избавляется от строк ... DEBUG и <?xml ..., затем делаем обертку и получаем полу-валидный файл.
Его не получится обработать xq, так как id написаны неверно: id=23243 а должны быть в кавычках: id="23243". Далее я просто открыл файл в текстовом редакторе и поправил эту ошибку. Получился valid.xml, по которому xq уже ищет.
Эту замену также можно сделать через sed, но я не стал добавлять это, скорее всего в исходном файле есть еще большая куча мусора, который придется вычистить перед обработкой.