我有这个csv文件
name;num_tel;num_fixe;id_client;num_comd;email;city;date_liv
gwenael;0998452223;1038431234;50C;12345;gwa@yahoo.fr;London;08/07/2015
marcel;0966442312;1038453211;31C;654321;marcel@yahoo.fr;Pairs;08/06/2015
judith;0954674487;1045227937;23D;78965;judith@yahoo.fr;Toulouse;11/05/2015
paul;0998452223;1038431234;35X;19945;paul@yahoo.fr;Bordeaux;01/04/2015
toto;0966442312;1038453211;31Z;994991;toto@yahoo.frNice;02/12/2015
marie;0954674487;1045227937;23C;78944;marie@yahoo.fr;Lille;04/08/2015
jacque;0998452223;1038431234;77C;18845;jacque@yahoo.fr;Bruges;09/05/2015
trucmuche;0966442312;1038453211;31Z;666321;trucmuche@yahoo.fr;Berlin;10/04/2015
tata;0954674487;1045227937;23D;77965;tata@yahoo.fr;New-york;08/07/2015
在我的情况下,那些标签名称是默认值,用户有可能拥有 更多标签名称例如我添加了城市,date_liv。所以他们添加它并生成csv。 它们出现在最后一个默认标签名称(电子邮件)之后。 我想知道是否可以创建一个循环来检查csv并将它们添加到xml? 我认为循环看起来像(i = 7; i< = 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 ) )
}
答案 0 :(得分:1)
这是对脚本的重写,允许将非默认的fld附加到每个“对象”类型(“C”和“D”)的已知字段。最值得注意的差异在BEGIN
块中,以及解析“header”行时会发生什么:
#!/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_flds
和d_flds
- 解析标头时。FNR==1
- 解析标头字段以创建cols
时,请检查dflt_flds[$i]
处的值。接下来,创建每个“对象”的默认fld。如果dlft
匹配“C”或空字符串,则将其视为c_flds
必填字段并添加到该数组中。 d_flds
的构造类似。id_client
字段以确定如何打印每个“C”和“D”类型“对象”,类似于它最初的完成方式(1),尽管“var”变量是保留并添加了一些注释。(1)这个答案是针对不同问题的a previous answer的修改。