2015-04-05 68 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