Чтение XML и извлечение только значения

gunzip -cбудет только записывать содержимое в стандартный вывод, а не распаковывать его.

Для ваших целей:

for a in {07..14}; do gunzip -c '201703'$a':02.out.gz'; done

0
02.03.2020, 23:05
2 ответа

Использование синтаксического анализатора XML из командной строкиxmlstarlet:

xmlstarlet sel -t -v '//entry[@key="cipher_strength"]/@value' -nl file.xml

Это будет соответствовать всем узлам entryв любом месте XML-документа и извлечет значение их атрибутов value, если тот же узел entryимеет атрибут key, значение которого равно cipher_strength. Каждое значение будет выводиться с завершающим символом новой строки.

Реализации xmllint, доступные в различных системах, по-видимому, различаются по поддержке выполнения запросов XPath.

В моей системе OpenBSD вы можете

xmllint --xpath '//entry[@key="cipher_strength"]/@value' file.xml

вернуться

 value="low"

Однако xmllint --xpath '//entry[@key="cipher_strength"]/@value/text()' file.xml, который, как я предполагал, даст мне строку low, похоже, не работает (просто генерирует ответ XPath set is empty).

Пока значения атрибута valueявляются «хорошими», вы должны иметь возможность массировать этот вывод, чтобы извлечь фактическое значение:

$ xmllint --xpath '//entry[@key="cipher_strength"]/@value' file.xml | sed -e 's/^[^"]*"//' -e 's/"$//'
low

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

Другие xmllintреализации/версии могли пойти по пути использованияxmllint --shell:

xmllint --shell file.xml <<<'cat //entry[@key="cipher_strength"]/@value' |
sed -e '/^[^ ]/d' -e 's/^[^"]*"//' -e 's/"$//'
2
28.04.2021, 23:21

Если нет доступных специальных инструментов XML, вы можете попробовать это с помощьюawk:вызова

user@host~$ awk '/key="cipher_strength"/ {for (i=1;i<=NF;i++) { if (split($i,parts,"=")==2 && parts[1]=="value") print parts[2]}}' file.xml

будет искать все строки, содержащие key="cipher_strength", а затем разделять все строки, разделенные пробелом -, по знаку =. Для всех тех, которые содержат этот знак «посередине» (, т. е. есть одна часть до и одна после него ), проверьте, равна ли первая часть value, и выведите вторую, если да. За ваш вклад я получаю

user@host~$ awk '/key="cipher_strength"/ {for (i=1;i<=NF;i++) { if (split($i,parts,"=")==2 && parts[1]=="value") print parts[2]}}' file.xml
"low"

Если узлов <node>больше, вы можете попытаться изменить программу, чтобы убедиться, что вы находитесь в нужном узле, прежде чем применять это действие.

0
28.04.2021, 23:21

Теги

Похожие вопросы