Как разобрать XML с помощью shellscript? [дубликат]
этот вопрос уже есть ответ здесь:
- Как разобрать XML в Bash? 14 ответов
Я хотел бы знать, что было бы лучшим способом проанализировать XML-файл с помощью shellscript ?
- нужно ли делать это вручную ?
- существует ли библиотека третьего уровня ?
Если вы уже сделали это, если вы могли бы дать мне знать, как вам удалось это сделать
11 ответов:
вы могли бы попробовать xmllint
программа xmllint анализирует один или несколько XML-файлы, указанные в командной строку как XML-файл. Он печатает различные типы выхода, в зависимости от выбранные параметры. Это полезно для обнаружение ошибок как в XML-коде, так и в XML парсере itse
Он позволяет выбирать элементы в XML-документе с помощью xpath, используя параметр --pattern.
на Mac OS X (Yosemite) он устанавливается с помощью по умолчанию.
В Ubuntu, если он еще не установлен, вы можете запуститьapt-get install libxml2-utils
вот полный рабочий пример.
Если это только извлечение адресов электронной почты, вы можете просто сделать что-то вроде:
1) Предположим, что XML-файл спам.XML-это как<spam> <victims> <victim> <name>The Pope</name> <email>pope@vatican.gob.va</email> <is_satan>0</is_satan> </victim> <victim> <name>George Bush</name> <email>father@nwo.com</email> <is_satan>1</is_satan> </victim> <victim> <name>George Bush Jr</name> <email>son@nwo.com</email> <is_satan>0</is_satan> </victim> </victims> </spam>
2) Вы можете получить электронные письма и обрабатывать их с помощью этого короткого кода bash:
#!/bin/bash emails=($(grep -oP '(?<=email>)[^<]+' "/my_path/spam.xml")) for i in ${!emails[*]} do echo "$i" "${emails[$i]}" # instead of echo use the values to send emails, etc done
результат этого примера:
0 pope@vatican.gob.va 1 father@nwo.com 2 son@nwo.com
важное замечание:
Не используйте это для серьезных дел. Это нормально для игры, получения быстрых результатов, изучения grep, так далее. но вы должны наверняка ищите, изучайте и используйте XML-парсер для производства (см. комментарий Михи ниже).
Я удивлен, что никто не упомянул xmlsh. Заявление о миссии:
оболочка командной строки для XML на основе философии и дизайна Оболочки Unix
xmlsh предоставляет знакомую среду сценариев, но в частности специально для сценариев xml-процессов.
список оболочек, как команды предоставляются здесь.
Я использую
xed
команда много, что эквивалентно кsed
для XML, и позволяетXPath
поиск и замена.
попробовать sgrep. Не совсем понятно, что вы пытаетесь сделать, но я, конечно, не буду пытаться написать XML-парсер в bash.
У вас установлен xml_grep? Это стандарт утилиты на основе perl для некоторых дистрибутивов (он был предварительно установлен в моей системе CentOS). Вместо того, чтобы давать ему регулярное выражение, вы даете ему выражение xpath.
довольно новый проект представляет собой XML-пакет coreutils в формате XML-кошка, в XML-СР, в XML-вырезать, в формате XML-файлов, ...
попробуйте использовать xpath. Вы можете использовать его для анализа элементов из xml-дерева.
http://www.ibm.com/developerworks/xml/library/x-tipclp/index.html
Это действительно выходит за рамки возможностей сценария оболочки. Сценарий оболочки и стандартные инструменты Unix хороши при разборе линейных ориентированных файлов, но все меняется, когда вы говорите о XML. Даже простые теги могут представлять проблему:
<MYTAG>Data</MYTAG> <MYTAG> Data </MYTAG> <MYTAG param="value">Data</MYTAG> <MYTAG><ANOTHER_TAG>Data </ANOTHER_TAG><MYTAG>
представьте, что вы пытаетесь написать сценарий оболочки, который может считывать данные, заключенные в нем . Три очень, очень простых примера XML показывают разные способы, которыми это может быть проблемой. Первые два примера являются точно таким же синтаксисом в XML. Третий просто атрибут, прикрепленный к нему. Четвертый содержит данные в другом теге. Просто
sed
,awk
иgrep
команды не могут поймать все возможности.вам нужно использовать полномасштабный язык сценариев, такой как Perl, Python или Ruby. Каждый из них имеет модули, которые могут анализировать XML-данные и облегчать доступ к базовой структуре. Я использую XML:: Simple в Perl. Мне потребовалось несколько попыток, чтобы понять это, но он сделал то, что мне нужно, и сделал моей программе много облегчающий.
вот функция, которая преобразует пары имя-значение XML и атрибуты в переменные bash.
http://www.humbug.in/2010/parse-simple-xml-files-using-bash-extract-name-value-pairs-and-attributes/
вот решение с использованием xml_grep (потому что xpath не был частью нашего дистрибутива, и я не хотел добавлять его ко всем производственным машинам)...
Если вы ищете определенную настройку в XML-файле, и если все элементы на данном уровне дерева уникальны, и нет атрибутов, то вы можете использовать эту удобную функцию:
# File to be parsed xmlFile="xxxxxxx" # use xml_grep to find settings in an XML file # Input (): path to setting function getXmlSetting() { # Filter out the element name for parsing local element=`echo | sed 's/^.*\///'` # Verify the element is not empty local check=${element:?getXmlSetting invalid input: } # Parse out the CDATA from the XML element # 1) Find the element (xml_grep) # 2) Remove newlines (tr -d \n) # 3) Extract CDATA by looking for *element> CDATA <element* # 4) Remove leading and trailing spaces local getXmlSettingResult=`xml_grep --cond $xmlFile 2>/dev/null | tr -d '\n' | sed -n -e "s/.*$element>[[:space:]]*\([^[:space:]].*[^[:space:]]\)[[:space:]]*<\/$element.*//p"` # Return the result echo $getXmlSettingResult } #EXAMPLE logPath=`getXmlSetting //config/logs/path` check=${logPath:?"XML file missing //config/logs/path"}
Это будет работать с этой структурой:
<config> <logs> <path>/path/to/logs</path> <logs> </config>
Он также будет работать с этим (но это не будет держать новые строки):
<config> <logs> <path> /path/to/logs </path> <logs> </config>
Если у вас есть дубликат
или или , то он вернет только последний. Вероятно, вы можете изменить функцию, чтобы вернуть массив, если он находит несколько совпадений. FYI: этот код работает на RedHat 6.3 с GNU BASH 4.1.2, но я не думаю, что я делаю что-то конкретное, поэтому должен работать везде.
Примечание: Для тех, кто новичок в сценарии, убедитесь, что вы используете правильные типы кавычек, все три используются в этом код (обычная одинарная кавычка '=литерал, обратная одинарная кавычка ' =execute и двойная кавычка "=group).