繁体   English   中英

Bash shell XML 至 CSV

[英]Bash shell XML to CSV

我必须使用 xmllint --shell 或 xmllint --xpath 将 xml 解析为 csv,因为我不允许安装其他软件包。

我需要 csv 中的名字和电话,仅此而已。 我尝试循环遍历 xml 并将其解析为 csv 文件,但问题是当名字有空格(例如 Mary Jane)或电话丢失时。 那么这种解决方案是行不通的。

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

或者这个组合解决方案,它将每个实体放在一个新行中:

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

是否有不同的方法来遍历 xml 文件?

XML 示例

给定一个 XML 文件file.xml

<PEOPLE>
    <PERSON>
        <FIRSTNAME>Alice</FIRSTNAME>
        <HOMEPHONE>555-1212</HOMEPHONE>
    </PERSON>
    <PERSON>
        <FIRSTNAME>Bob</FIRSTNAME>
        <HOMEPHONE>123-4567</HOMEPHONE>
    </PERSON>
</PEOPLE>

然后

echo 'cat (//FIRSTNAME | //HOMEPHONE)/text()' | xmllint --shell file.xml

输出

/ >  -------
Alice
 -------
555-1212
 -------
Bob
 -------
123-4567
/ >

这很容易用 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

太糟糕了,你不能安装其他工具: 可以很容易地按照你喜欢的方式格式化你的 output:

xmlstarlet sel -t -m //PERSON -v ./FIRSTNAME -o , -v ./HOMEPHONE -n file.xml
Alice,555-1212
Bob,123-4567

在您提供的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

它不是最干净的,但不幸的是, xmllint仅支持 Xpath 1.0,否则可以在一个命令中完成。

编辑:结果应该是这样的:

Michael ,7800002814
E,7800907671
Ryan,7909355223

您可以通过以下方式使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM