2017-02-10 46 views
1

Задача:Получить значение атрибута из XML-тегов с помощью сценария оболочки и конвертировать в CSV

Я пытаюсь получить значение атрибута из XML-тегов с помощью сценария оболочки, разделить значение и сохранить их в CSV-файле.

Это как XML выглядит следующим образом:

<host> 
    <servers> 
    <server name="Type1Name1-Port1" >...</server> 
    <server name="Type2Name2-Port2" >...</server> 
    <server name="Type3Name3-Port3" >...</server> 
    ... 
    <server name="TypexNamex-Portx" >...</server> 
    </servers> 
</host> 

Я хотел бы получить значение от «имени» и разделить атрибут по их как следующему:
Type;Name;Port

Выхода CSV-файл Я хочу, должен выглядеть следующим образом:

Type1;Name1;Port1 
Type2;Name2;Port2 
Type3;Name3;Port3 
... 
Typex;Namex;Portx 

проблема:

  • Я ничего не могу установить на сервере
  • я могу использовать только "КШ-AWK"/"xmllint wihtout --xpath"/"стандартные команды Linux"

я могу используйте любой shell-язык, который я хочу. Я предпочитаю bash и ksh.

Мои вопросы:

  • Как вы думаете, можно решить мою задачу?
  • Каков наилучший подход для подзадач? (Чтение, расщепление, запись)

РЕДАКТИРОВАТЬ:

Пример данные имя-сервера в:

Т-TTT_AAA-А-ССС-РРРР

Где T представляет тип, A имя приложения, S имя сервера, P порт. Длина T, A и S является переменной. P постоянна.

+0

Да, это должно быть возможно с соединением 'xmllint --shell' и' awk' или ' sed'. Что такое разделитель между вашими «Type1» и «Name1»? Капитализация? – Aserre

+0

Не могли бы вы показать пример с использованием реальных данных (или данных, имеющих форму, аналогичную той, что у вас есть)? Это должно быть важно для части awk – Aserre

+0

@Aserre .. Done .. –

ответ

1

Вот что я придумал, используя только общие инструменты: xmllint и sed:

echo 'cat //host/servers/server/@name' | xmllint --shell data.xml | sed -n 's: name=\"\([A-Z][a-z0-9]*\)\([A-Z][a-z0-9]*\)-\(.*\)\":\1,\2,\3:p' 

В sed часть делается в соответствии с примерами Op в момент оприходования.

Разбивка:

  • echo 'cat //host/servers/server/@name': мы передаем эту команду xmllint. Он поймает атрибут name всех узлов внутри <host><servers><server ...> ... </server></servers></hosts>
  • xmllint --shell data.xml: Итерации через data.xml и выполняет команды, переданные как аргумент в интерактивной оболочке.
  • sed -n 's: name=\"\([A-Z][a-z0-9]*\)\([A-Z][a-z0-9]*\)-\(.*\)\":\1;\2;\3:p': мы обрабатываем выход xmllint только сохранить данные, мы заинтересованы
    • xmllint произведет следующий вывод: name="Type1Name1-Port1"
    • Определим 3 захвата группы: заглавные буквы, за которой следует любой символ, кроме капитала (для Type), другая заглавная буква, за которой следует любой символ, кроме капитала (для Name), и любой символ между символами - и "
    • Мы сообщаем sed, чтобы печатать только согласованные trings, разделённые полуколоннами

Выход:

Type1;Name1;Port1 
Type2;Name2;Port2 
Type3;Name3;Port3 
Typex;Namex;Portx 

EDIT:

Для установки шаблона Вы указали в комментариях, вы просто должны изменить SED регулярное выражение, например:

sed -n 's: name=\"\(.*\)_\(.*\)-\(.\{4\}\)\":\1,\2,\3:p' 

Это будет соответствовать формату T-TTT_AAA-A-SSS-PPPP, с любой длиной для имени типа и сервера. Попытайтесь возиться с регулярным выражением или задать другой вопрос в теге regex, если это не совсем то, что вам нужно.

+0

Это сработало для меня. Спасибо. Но если есть еще один тег с атрибутом «имя», не будет ли фальсификация вывода? –

+0

Нет, он будет специально искать атрибут «name» внутри тега . – Aserre

+0

Но нет части инструкции: 'sed -n 's: name = \" \ (. * \) _ \ (. * \) - \ (. \ {4 \} \) \ ": \ 1, \ 2, \ 3: p'' говорит, что он должен находиться внутри тега . –

0

Без xmllint вы можете разобрать вход как

<host> 
    <servers> 
    <server name="Type1_Name1-Port1" >...</server> 
    <server name="Type-2_Name2-Port2" >...</server> 
    <server name="Type3_Name-3-Port3" >...</server> 
    </servers> 
</host> 

с

sed -n '/<server name=/ s/[^"]*"\([^_]*\)_\([^"]*\)-\([^"]*\)".*/\1;\2;\3/p' inputfile 
+0

Works. См. Принятый ответ для более мелкого заявления с точным выводом. –