【问题标题】:correct Awk expression to parse xml to csv正确的 awk 表达式以将 xml 解析为 csv
【发布时间】:2015-07-06 05:45:02
【问题描述】:

我写了一个表达式来将我的 xml 解析为 CSV,但它不起作用,请帮我解决这个问题。我这样做是因为我不能在服务器上使用像 xmlstarlet 这样的解析器。

这是我的 xml

<?xml version="1.0"?>
<root>
  <record>
   <country>US</country>  
  <data>
            <id_client>50C</id_client>  
            <mail>1@mail.com</mail>
            <adress>10  </adress>
            <num_tel>001</num_tel>
            <name>toto</name>
            <birth>01/30/008</birth>        
  </data> 
  <data>
            <id_client>100K</id_client>  
            <mail>2@mail.com</mail>
            <adress>10  </adress>
            <num_tel>002</num_tel>
            <name>toto2</name>
            <birth>01/30/011</birth>                    
  </data> 
 </ record>
 <record>
   <country>China</country>  
  <data>
            <id_client>99E</id_client>  
            <mail>3@mail.com</mail>
            <adress>10  </adress>
            <num_tel>003</num_tel>
            <name>toto3</name>
            <birth>01/30/0008</birth>       
  </data> 
  <data>
            <id_client>77B</id_client>  
            <mail>4@mail.com</mail>
            <adress>10  </adress>
            <num_tel>004</num_tel>
            <name>toto4</name>
            <birth>2001/05/01</birth>                   
  </data> 
  </record
  </root>

我需要的输出:

 country;id_client;name
 US;50C;toto1
 US;100K;toto2
 China;99E;toto3
 China77B;toto4

最后我正在尝试更新我的语法:

/<country>/{sub(".*<country[^>]+><[^>]+>","",$0);sub("<.*","",$0);s=s";"$0}/<\/country>/{sub("^;","",s);print s;s=""}

【问题讨论】:

  • 服务器上是否有可用的 perl?还是蟒蛇?还是红宝石? 其中任何一个 都更适合这项任务(通过它们对 actual xml 的支持)然后 awk 是。
  • @EtanReisner 还有一个用于 gawk 的 XML 库。请参阅 awk.info/?Xgawksourceforge.net/projects/gawkextlib/files/xgawk。警告:我从未使用过它,所以这就是我所知道的一切。
  • @EdMorton 感谢您的链接。我知道我以前看过它,但是当我想引用它时,却一直找不到它。

标签: xml csv awk


【解决方案1】:

如果您的数据总是像您显示的那样每行放置一个条目,并且没有古怪的空白介入:

$ cat tst.awk
BEGIN {
    FS="[><]"; OFS=";"
    n = split("country id_client name",tags,/ /)
    for (i=1; i<=n; i++) {
        printf "%s%s", tags[i], (i<n?OFS:ORS)
    }
 }
{ tag2val[$2] = $3 }
/<\/data>/ {
    for (i=1; i<=n; i++) {
        printf "%s%s", tag2val[tags[i]], (i<n?OFS:ORS)
    }
}

$ awk -f tst.awk file
country;id_client;name
US;50C;toto
US;100K;toto2
China;99E;toto3
China;77B;toto4

如果您以后关心不同或额外的标签,只需将它们添加到split() 命令中的列表中即可。

【讨论】:

  • 很好,效果很好!谢谢。我越来越了解拆分在 awk 中的重要性
猜你喜欢
  • 2015-06-20
  • 1970-01-01
  • 2015-08-08
  • 2012-01-25
  • 1970-01-01
  • 2015-04-29
  • 2012-05-18
  • 1970-01-01
  • 2012-07-01
相关资源
最近更新 更多