2015-03-31 53 views
1

我想使用awk將csv轉換爲xml文件。爲了更好地理解我給我的csv文件的爲例:csv到xml命令行和條件

name;num_tel;num_fixe;id_client;num_comd  
gwenael;0998452223;1038431234;50C;12345 
marcel;0966442312;1038453211;31C;654321  
judith;0954674487;1045227937;23D;78965 
paul;0998452223;1038431234;35X;19945 
toto;0966442312;1038453211;31Z;994991 
marie;0954674487;1045227937;23C;78944 
jacque;0998452223;1038431234;77C;18845 
trucmuche;0966442312;1038453211;31Z;666321 
tata;0954674487;1045227937;23D;77965 

我的目標,是要id_client的第三個字母(C,d,X,Z),如果例如: 字母是C的XML我將只有標籤名稱,num_comd和tel_fixe。 如果這封信是我d將有標籤名,id_client,num_fixe

我在服用封信awk腳本管與指揮切成功,並把它放在一個變量 現在我'在這裏:

if(var==C) 
    {} 
Else if (var==D) 
{} 

你能幫我解決一下關於如何輸入正確的xml標籤的問題嗎? 我很新的命令行。

抱歉寫錯了。我是法國人。

回答

1

下面是一個可執行的awk腳本例子,我在那裏創建了幾個輔助函數來重新使用代碼:

#!/usr/bin/awk -f 

BEGIN { 
    FS=";" 
    documentEnclosingTag = "rows" 
    c_flds["name"]; c_flds["num_comd"]; c_flds["num_tel"] 
    d_flds["name"]; d_flds["id_client"]; d_flds["num_fixe"] 
    x_flds["name"] 
    z_flds["name"] 

    print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 
    printf "<%s>\n", documentEnclosingTag 
} 

FNR==1 { gsub(" ", ""); for(i=1; i<=NF; i++) cols[$i]=i; next } 

$(cols["id_client"]) ~ /C$/ { print createObject("C", c_flds) } 
$(cols["id_client"]) ~ /D$/ { print createObject("D", d_flds) } 
$(cols["id_client"]) ~ /X$/ { print createObject("X", x_flds) } 
$(cols["id_client"]) ~ /Z$/ { print createObject("Z", z_flds) } 

END { printf "</%s>\n", documentEnclosingTag } 

#----------- functions ----------- 

function createObject(enclosingTag, flds,   key, s) { 
    for(key in flds) { 
     s = s "\t" wrapData(key, $(cols[key])) "\n" 
    } 
    return(wrapData(enclosingTag, "\n" s)) 
} 

function wrapData(enclosingTag, data) { 
    return(sprintf("<%s>%s</%s>", enclosingTag, data, enclosingTag)) 
} 

你可以把這個文件(script.awk),使其可執行文件,然後運行它像

./script.awk data > data.xml 

其中data是我給你的數據文件的名稱,而data.xml是數據最終的結果。

輸出是這樣的:

<?xml version="1.0" encoding="UTF-8"?> 
<rows> 
<C> 
     <num_tel>0998452223</num_tel> 
     <name>gwenael</name> 
     <num_comd>12345 </num_comd> 
</C> 
<C> 
     <num_tel>0966442312</num_tel> 
     <name>marcel</name> 
     <num_comd>654321  </num_comd> 
</C> 
<D> 
     <id_client>23D</id_client> 
     <num_fixe>1045227937</num_fixe> 
     <name>judith</name> 
</D> 
<X> 
     <name>paul</name> 
</X> 
<Z> 
     <name>toto</name> 
</Z> 
<C> 
     <num_tel>0954674487</num_tel> 
     <name>marie</name> 
     <num_comd>78944</num_comd> 
</C> 
<C> 
     <num_tel>0998452223</num_tel> 
     <name>jacque</name> 
     <num_comd>18845</num_comd> 
</C> 
<Z> 
     <name>trucmuche</name> 
</Z> 
<D> 
     <id_client>23D</id_client> 
     <num_fixe>1045227937</num_fixe> 
     <name>tata</name> 
</D> 
</rows> 

我敢肯定,我不使用XML文件的各個部分正確的術語,但這種輸出可通過瀏覽器爲「有效」加載(可解析)XML。如果這個文件應該提供給任何其他人,你可能會想看看DTD。

這裏的一般故障:

  • BEGIN塊,場分離器設置爲;,初始化像對於每個「對象」中選擇所需的輸出場變量和documentEnclosingTag,然後打印連同通用XML頭documentEnclosingTag
  • FNR==1塊中,將數據的第一行作爲標題並將它們放入cols數組中,以便稍後可以通過標題名稱引用它們。用gsub調用清理數據以修剪列名
  • 對於每個$(cols["id_client"])塊,通過指定enclosingTag值和匹配所需的flds數組來打印適當的「對象」。
  • END,打印閉documentEnclosingTag

至於功能:

  • wrapData創建具有包圍周圍的數據的標籤的字符串。
  • createObject使用wrapData爲「Object」本身創建元素和封閉標籤,其中我使用awk的標準字符串連接添加了一些輸出格式。 flds數組表示所需的輸出字段。 keys是函數的局部變量。每個fld,數據和標籤連接到s,然後s最後被enclosingTag包裝並作爲字符串返回。
+0

非常感謝你的教程,我極力想法,我試圖適應我的代碼,並且我會回過頭來問你。 – iceman225 2015-04-01 15:04:14

+0

我回來了,關於如何檢查這封信的問題,以id_client的C爲例。如果例如而不是50C,我們有50C0145。我該怎麼做 ?謝謝 – iceman225 2015-04-02 09:06:01

+0

分解'$(cols [「id_client」])〜/ C $ /'就像是說「匹配第四個fld的值與正則表達式匹配的記錄,其中'C'在字段的末尾」。從'/ C $ /'中刪除'$'會執行你想要的操作:'$(cols [「id_client」])〜/ C /'。檢查每個部分:'$(cols [「id_client」])'=>'$(4)'=>'$ 4','〜'=>「匹配」,'/ C $ /'=>正則表達式在'〜'之前的字段末尾的'C'。 – n0741337 2015-04-02 14:08:23

1

下面是使用您提供的示例數據讀取名爲in的文件的示例。

awk -F\; '$4~/C/ {print "<name>"$1"</name>"} $4~/D/{print "<name>"$1"</name><id_client>"$4"</id_client>"}' < in 

您應該可以填寫您需要擴展此示例的額外xml元素。

此命令的輸出是: <name>gwenael</name> <name>marcel</name> <name>judith</name><id_client>23D</id_client> <name>marie</name> <name>jacque</name> <name>tata</name><id_client>23D</id_client>