[英]Bash shell XML to CSV
I have to parse xml to csv, using xmllint --shell or xmllint --xpath, because I'm not allowed to instal additional packages.我必须使用 xmllint --shell 或 xmllint --xpath 将 xml 解析为 csv,因为我不允许安装其他软件包。
I need firstname and phone in the csv, and nothing else.我需要 csv 中的名字和电话,仅此而已。 I tried this to loop through an xml and parse it to csv file, but the problem is when First name has space (for example Mary Jane) or the phone is missing.我尝试循环遍历 xml 并将其解析为 csv 文件,但问题是当名字有空格(例如 Mary Jane)或电话丢失时。 Then this kind of solution does not work.那么这种解决方案是行不通的。
for f in $(echo 'cat //FIRSTNAME/text()' | xmllint --shell TEST.xml | sed '1d;$d' | sed 's/-------//')
do
echo $f >> $CSV_FILE_NAMES
done
for i in $(echo 'cat //HOMEPHONE/text()' | xmllint --shell TEST.xml | sed '1d;$d' | sed 's/-------//')
do
echo $i >> $CSV_FILE_PHONES
done
paste -d "," $CSV_FILE_NAMES $CSV_FILE_PHONES >> $CSV
Or this combined solution, which places every entity in a new line:或者这个组合解决方案,它将每个实体放在一个新行中:
for f in $(echo 'cat //FIRSTNAME/text()|//HOMEPHONE/text()' | xmllint --shell TEST.xml | sed '1d;$d' | sed 's/-------//')
do
echo $f >> $CSV_FILE
done
Mark
9999999999
Jack
8888888888
Is there a different way to loop through an xml file?是否有不同的方法来遍历 xml 文件?
Given an XML file file.xml
给定一个 XML 文件file.xml
<PEOPLE>
<PERSON>
<FIRSTNAME>Alice</FIRSTNAME>
<HOMEPHONE>555-1212</HOMEPHONE>
</PERSON>
<PERSON>
<FIRSTNAME>Bob</FIRSTNAME>
<HOMEPHONE>123-4567</HOMEPHONE>
</PERSON>
</PEOPLE>
Then然后
echo 'cat (//FIRSTNAME | //HOMEPHONE)/text()' | xmllint --shell file.xml
outputs输出
/ > -------
Alice
-------
555-1212
-------
Bob
-------
123-4567
/ >
which is readily parsable with awk, among other tools:这很容易用 awk 和其他工具解析:
echo 'cat (//FIRSTNAME | //HOMEPHONE)/text()' | xmllint --shell file.xml | awk '
NR % 4 == 2 {printf "%s,", $0}
NR % 4 == 0 {print $0}
'
Alice,555-1212
Bob,123-4567
Too bad you can't install other tools: xmlstarlet makes it pretty easy to format your output the way you like:太糟糕了,你不能安装其他工具: xmlstarlet可以很容易地按照你喜欢的方式格式化你的 output:
xmlstarlet sel -t -m //PERSON -v ./FIRSTNAME -o , -v ./HOMEPHONE -n file.xml
Alice,555-1212
Bob,123-4567
In The XML Sample that you have provided, I think it would be simpler to loop over all the ZVM_DATA then use the XPath concat function to concatenate the FIRSTNAME, HOMEPHONE, or any other fields you'd like to include:在您提供的XML中,我认为在所有ZVM_DATA上循环会更简单,然后使用ZB6454D498635710A189189184EA13BEED1C1C11C11C11C11C11C11C11C11C11C11C11C11C11C11C11C11C11C11C11C11C11C11C11C11C11C118NFENTENTENTENTENTENTEATENTEATENTEATENTEATENTEATENTEANTEATENTEANTEATENTERYETENE
for index in $(seq $(xmllint --xpath "count(//ZVM_DATA)" test.xml))
do
xmllint --xpath "concat(//ZVM_DATA[$index]/FIRSTNAME/text(),',',//ZVM_DATA[$index]/HOMEPHONE/text())" --format test.xml
done
It is not the cleanest but unfortunately, xmllint supports only Xpath 1.0 otherwise it could be done in one command.它不是最干净的,但不幸的是, xmllint仅支持 Xpath 1.0,否则可以在一个命令中完成。
Edit: the result should look like this:编辑:结果应该是这样的:
Michael ,7800002814
E,7800907671
Ryan,7909355223
You can use awk
in a following way您可以通过以下方式使用awk
awk 'BEGIN{FS="[<|>]"} /FIRSTNAME/ { v1=$3 } /HOMEPHONE/ { v2=$3 } /\/ZVM_DATA/ {printf "%s, %s\n", v1, v2}'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.