gunzip -c
будет только записывать содержимое в стандартный вывод, а не распаковывать его.
Для ваших целей:
for a in {07..14}; do gunzip -c '201703'$a':02.out.gz'; done
Использование синтаксического анализатора 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/"$//'
Если нет доступных специальных инструментов 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>
больше, вы можете попытаться изменить программу, чтобы убедиться, что вы находитесь в нужном узле, прежде чем применять это действие.