2014-02-02 3 views
1

Я пытаюсь создать скрипт bash для анализа XML-файла и сохранения его в файл csv.Создание скрипта bash для синтаксического анализа файла xml в csv

Например:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <List> 
    <Job id="1" name="John/> 
    <Job id="2" name="Zack"/> 
    <Job id="3" name="Bob"/> 
</List> 

Я хотел бы сценарий, чтобы сохранить информацию в файл CSV, как, например:

John | 1 
Zack | 2 
Bob | 3 

Имя и идентификатор будет в другой ячейке.

Есть ли способ, которым я могу это сделать?

+0

Возможно, вы только что отредактировали старый вопрос (http://stackoverflow.com/q/21495533/3076724) вместо того, чтобы публиковать новый, но при публикации похожих вопросов обязательно должны быть связаны с ним. – BroSlow

+0

Duplicate: https://stackoverflow.com/questions/14368347/convert-xml-file-to-csv-in-shell-script – Vanuan

ответ

2

Try что-то вроде этого

#!/bin/bash 
while read -r line; do 
    [[ $line =~ "name=\""(.*)"\"" ]] && name="${BASH_REMATCH[1]}" && [[ $line =~ "Job id=\""([^\"]+) ]] && echo "$name | ${BASH_REMATCH[1]}" 
done < file 

Линия с John имеет неверный формат. С его фиксированным, например, выход

John | 1 
Zack | 2 
Bob | 3 
+1

в этом примере 'name =" John /> ', нет двойной квоты после Джона , поэтому рекомендуем заменить '[[$ line = ~" name = \ "" (. *) "\" "]]' to '[[$ line = ~" name = \ "" ([^ \ "|/] *)]] ' – BMW

+1

@BMW Спасибо. Я предположил, что он не должен быть искаженным xml, но если он может сделать это или что-то вроде' ([A-Za-z] *) ' – BroSlow

+0

чувак, вы можете уточнить этот короткий сценарий? Я очень смущен. :) Тем не менее, он выглядит безумно хорошим. – Dominik

4

Вы отправили запрос, подобный вашему pervious one. Я бы снова предложил использовать синтаксический анализатор XML. Можно сказать:

xmlstarlet sel -t -m //List/Job -v @name -o "|" -v @id -n file.xml 

Было бы вернуть

John|1 
Zack|2 
Bob|3 

для данных образцов.

Направьте вывод sed: sed "s/|/\t| /" если вы хотите, чтобы появляются как в вашем примере.

1

Использование СЭД

sed -nr 's/.*id=\"([0-9]*)\"[^\"]*\"(\w*).*/\2 | \1/p' file 

Дополнительная, база на cript BroSlow, я объединить варианты.

#!/bin/bash 

while read -r line; do 
    [[ $line =~ id=\"([0-9]+).*name=\"([^\"|/]*) ]] && echo "${BASH_REMATCH[2]} | ${BASH_REMATCH[1]}" 
done < file 
0

Расширение XMLStarlet подход:

Учитывая этот XML-файл:

<DATA> 
    <RECORD> 
    <NAME>John</NAME> 
    <SURNAME>Smith</NAME> 
    <CONTACTS> 
     "Smith" LTD, 
     London, Mtg Str, 12, 
     UK 
    </CONTACTS> 
    </RECORD> 
</DATA> 

И этот сценарий:

xmlstarlet sel -e utf-8 -t \ 
    -o "NAME, SURNAME, CONTACTS" -n \ 
    -m //DATA/RECORD \ 
    -o "\"" \ 
    -v $"str:replace(normalize-space(NAME, '\"', '\"\"')" -o "\",\"" \ 
    -v $"str:replace(normalize-space(SURNAME),  '\"', '\"\"')" -o "\",\"" \ 
    -v $"str:replace(normalize-space(CONTACTS), '\"', '\"\"')" -o "\",\"" \ 
    -o "\"" \ 
    -n file.xml 

Вы будете иметь следующий вывод:

NAME, SURNAME, CONTACTS 
"John", "Smith", """Smith"" LTD, London, Mtg Str, 12, UK" 
Смежные вопросы