2015-04-05 39 views
0

xml的我有這個csv文件的CSV各種標籤名稱

name;num_tel;num_fixe;id_client;num_comd;email;city;date_liv 
gwenael;0998452223;1038431234;50C;12345;[email protected];London;08/07/2015 
marcel;0966442312;1038453211;31C;654321;[email protected];Pairs;08/06/2015 
judith;0954674487;1045227937;23D;78965;[email protected];Toulouse;11/05/2015 
paul;0998452223;1038431234;35X;19945;[email protected];Bordeaux;01/04/2015 
toto;0966442312;1038453211;31Z;994991;[email protected];02/12/2015 
marie;0954674487;1045227937;23C;78944;[email protected];Lille;04/08/2015 
jacque;0998452223;1038431234;77C;18845;[email protected];Bruges;09/05/2015 
trucmuche;0966442312;1038453211;31Z;666321;[email protected];Berlin;10/04/2015 
tata;0954674487;1045227937;23D;77965;[email protected];New-york;08/07/2015 

在我的情況下,這些標籤名稱是默認值,用戶有可能到了 更多的標記名稱爲例,我增加城市, date_liv。所以他們添加它並生成csv。它們出現在最後一個默認標記名稱(電子郵件)之後。 我想知道是否有可能使循環檢查到CSV並將它們添加到XML? 我認爲循環看起來像(i = 7;我< = NF; i ++){}?但如何做到這一點? 這裏是我做的,你能幫助我很好地形成它,請我有這麼多的錯誤

BEGIN { 

FS=";" 
documentEnclosingTag = "rows" 
c_flds["id_client"];c_flds["name"];c_flds["num_cmd"];c_flds["num_tel"];d_flds["email"] 
d_flds["id_client"];d_flds["name"];d_flds["num_fixe"];d_flds["num_tel"]; 

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 } 

var = $(cols["ID_client_proxy"]) 
if (var ~ /C/) 
{ print createObject("C", c_flds) } 
else { print createObject("D", d_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)) 
} 
+1

你應該習慣測試你發佈的腳本以及顯示所需的輸出。在這種情況下,我對另一個問題很熟悉。您也可能希望將測試數據縮短爲一個標題,一個「C」和一個「D」。 – n0741337 2015-04-05 17:44:56

回答

1

這裏的腳本的改寫,允許非默認FLDS附加到每個已知油田「對象「類型(」C「和」D「)。最noteable區別在於BEGIN塊當「頭」行被解析會發生什麼:

#!/usr/bin/awk -f 

BEGIN { 

    FS=";" 
    documentEnclosingTag = "rows" 

     # name the default flds with "_", "C" and "D" represent "Objects" 
    dflt_flds["id_client"] = "_CD" 
    dflt_flds["name"]  = "_CD" 
    dflt_flds["num_comd"] = "_C" 
    dflt_flds["num_tel"] = "_CD" 
    dflt_flds["email"]  = "_C" 
    dflt_flds["num_fixe"] = "D" 

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

FNR==1 { 
    gsub(" ", "") 
    for(i=1; i<=NF; i++) { 
     cols[$i]=i 
     dflt = dflt_flds[$i] 
     if(dflt ~ /C/ || dflt == "") c_flds[$i] 
     if(dflt ~ /D/ || dflt == "") d_flds[$i] 
    } 
    next 
} 

    # set var for every record read 
{ var = $(cols["id_client"]) } 

    # use var to determine which kind of record to print 
var ~ /C/ { print createObject("C", c_flds) } 
var ~ /D/ { print createObject("D", d_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)) 
} 
  • BEGIN - 而不是命名每個默認列,我們需要爲默認的一種「位掩碼」和每個「對象」類型。因此,使用dflt_flds數組創建該數組,該數組命名每個已知列與每個可能的數據類型相關聯。 _被保留以表示默認或其他已知字段。如果_是一個有效的「id_client」標識符,則需要將其更改爲另一個字符。其他字段的默認值在該字符串中用「C」或「D」值表示。請注意,c_fldsd_flds稍後會構建 - 解析標頭時。
  • FNR==1 - 當解析標題字段以創建cols時,請檢查dflt_flds[$i]處的值。接下來,創建每個「對象」的默認fld。如果dlft匹配「C」或空字符串,則它被視爲c_flds必填字段並添加到該數組中。 d_flds的構造相似。
  • 之後,id_client字段被用來確定如何打印每個「C」和「D」類型的「對象」,類似於它最初完成的方式(1),雖然「var」變量被保留,添加。

(1)這個答案的a previous answer爲一個不同的問題的變形例。

+0

非常感謝!它工作正常,並且很抱歉如果我沒有把我想要的輸出。還有一個問題!涉及外部變量。我怎樣才能在腳本中收到它?我必須從外殼腳本接收變量,變量假設(v)等於摩托車,汽車或飛機。所以,例如,如果我收到V =「飛機」,我怎麼能把它放在標籤名稱飛機爲我的所有客戶(C,D) – iceman225 2015-04-07 13:31:04

+0

我忘了告訴你變量來自外殼腳本 – iceman225 2015-04-07 15:03:22

+0

Awk有一個'-v'標誌來接受外部變量。像'-v -v = plane'一樣使用它,你可以將一個變量'v'傳遞給腳本。在內部,你可以硬編碼添加「locomotion」標籤或使用另一個'-v'標誌。相反,我會建議一個單獨的'defaults'文件,指定爲'CD locomotion plane',在這種情況下,將'dflt_flds'的構造移動到'FNR == NR'塊來讀取'defaults'現在,默認值。然後這些默認值可以傳遞給'c_flds'等,然後一個改變的'createObject()'可以打印'data'或'defaults'的值。 – n0741337 2015-04-07 16:41:21