csv到xml命令行和条件

时间:2015-03-31 16:27:26

标签: xml csv awk

我正在尝试使用awk将csv转换为xml文件。为了更好地理解我给出了我的csv文件的例子:

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)的第三个字母,例如: 字母是x中的C我将只有标签名称,num_comd和tel_fixe。 如果字母是D,我将有标签名称,id_client,num_fixe

我成功地用带有命令剪切的awk脚本管道取出了这封信并将其放入变量中 现在我在这里:

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

您能否帮我解决一下输入正确的xml标签的问题? 我是命令行的新手。

抱歉写作错误。我是法国人。

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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数组中,以便稍后可以通过标题名称引用flds。通过gsub调用来清理数据以修剪列名称
  • 对于每个$(cols["id_client"])块,通过指定enclosingTag值和匹配的所需flds数组,打印适当的“对象”。
  • END中,打印结束documentEnclosingTag

至于功能:

  • wrapData创建一个包含数据周围标签的字符串。
  • createObject使用wrapData为“对象”本身创建元素和封闭标记,其中我使用awk的标准字符串连接添加了一些输出格式。 flds数组表示所需的输出字段。 keys是函数的局部变量。每个fld,数据和标记都会连接到s,最后s会被enclosingTag包装并作为字符串返回。