2015-04-27 42 views
1

我寫了一個表達式來將我的xml解析爲CSV,但它不起作用,請幫助我。我這樣做是因爲我不能在服務器上使用像xmlstarlet這樣的解析器。正確的awk表達式將xml解析爲csv

這裏是我的xml

<?xml version="1.0"?> 
<root> 
    <record> 
    <country>US</country> 
    <data> 
      <id_client>50C</id_client> 
      <mail>[email protected]</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>[email protected]</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>[email protected]</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>[email protected]</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 

而且finaly我的語法我'嘗試更新:

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

你有服務器上的perl嗎?還是python?還是紅寶石? *任何*這些更適合這項任務(他們支持* actual * xml),那麼awk就是。 –

+1

@EtanReisner還有一個用於gawk的XML庫。請參閱http://awk.info/?Xgawk和http://sourceforge.net/projects/gawkextlib/files/xgawk/。警告:我從來沒有使用過,這是我所知道的。 –

+1

@EdMorton感謝您的鏈接。我知道我以前曾見過它,但當我想參考它時,卻一直未能再次找到它。 –

回答

3

如果你的數據的總是按照每行顯示一條條目,而不顯示任何古怪的白色空間:

$ 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()命令的列表中即可。

+3

偉大的工程太棒了!謝謝。我越來越明白awk中的分割是如此重要 – iceman225