Как разобрать 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).