Синтаксический анализ XML атрибутов с bash - PullRequest
0 голосов
/ 05 апреля 2020

Мне нужно получить атрибуты из файла XML с помощью чистого сценария bash.

Итак, у меня есть следующий файл XML с элементом root Group и множеством Person элементов, каждый из которых имеет атрибуты id и username. id является уникальным значением для каждого элемента:

<?xml version="1.0" encoding="UTF-8"?>
<Group id="D_8"
       main="false">

    <Person id="P_0001"
            email="email0001@example.com"
            username="person_0001"
            password="pass_0001"
            active="true"/>

    <Person id="P_0002"
            email="email0002@example.com"
            username="person_0002"
            password="pass_0002"
            active="true"/>

    <!--  ...and hundreds of other Person elements ...  -->
</Group>

И мне нужно использовать скрипт bash для извлечения атрибутов id и username в некоторую структуру значения ключа:

P_0001=person_0001
P_0002=person_0002

Проверены другие связанные ответы, но большинство из них предлагают использовать некоторые XML парсеры, такие как xmllint. Но, к сожалению, у меня их нет на целевой машине.

Подскажите, пожалуйста, как мне этого добиться.

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

Допущения:

  • файл xml «красиво» отформатирован в качестве представленного примера (следовательно, нет необходимости в XML синтаксическом анализаторе)
  • Person id и username написаны в точности так, как они представлены, и отображаются только в разделе Group

Один awk решение:

awk -F'"' '
/Person id/ { pid=$2 ; next }
/username/  { printf "%s=%s\n", pid, $2 ; next }
' xml.dat

Где:

  • -F '"" - использовать двойные кавычки (") в качестве разделителя полей
  • /Person id/ - сохранить поле № 2 в переменной pid
  • /username/ - вывести нашу переменную pid + '=' + имя пользователя (опять же, поле # 2)
  • xml.dat - имя XML файла

Запуск этого решения awk для данных примера файл генерирует:

P_0001=person_0001
P_0002=person_0002

Все ставки отключены, если мои предположения неверны.

1 голос
/ 05 апреля 2020

До тех пор, пока атрибут username не предшествует атрибуту id, это скрипт bash для выдачи результата:

#/usr/bin/env bash

id='\bid="([^"]+)"'
username='\busername="([^"]+)"'
while IFS= read -r line; do
    [[ $line =~ $id       ]] && idv="${BASH_REMATCH[1]}"
    [[ $line =~ $username ]] && echo "$idv=${BASH_REMATCH[1]}"
done < data.xml
exit 0

Он работает, даже если атрибут username и id атрибут находится в одной строке.

...