我正在尝试编写一个awk脚本,将CSV格式的电子表格转换为XML以用于Bugzilla错误。输入CSV的格式如下(从XLS电子表格创建并保存为CSV):
tag_1,tag_2,...,tag_N
value1_1,value1_2,...,value1_N
value2_1,value2_2,...,value2_N
valueM_1,valueM_2,...,valueM_N
标题列表示XML标记的名称。转换为XML的上述文件应如下所示:
<element>
<tag_1>value1_1</tag_1>
<tag_2>value1_2</tag_2>
...
<tag_N>value1_N</tag_N>
</element>
<element>
<tag_1>value2_1</tag_1>
<tag_2>value2_2</tag_2>
...
<tag_N>value2_N</tag_N>
</element>
...
我必须完成的awk脚本如下:
BEGIN {OFS = "\n"}
NR == 1 {for (i = 1; i <=NF; i++)
tag[i]=$i
print "<bugzilla version=\"3.4.1\" urlbase=\"http://mozilla.com/\" maintainer=\"somebody@mozilla.com\" exporter=\"somebody.else@mozilla.com\">"}
NR != 1 {print " <bug>"
for (i = 1; i <= NF; i++)
print " <" tag[i] ">" $i "</" tag[i] ">"
print " </bug>"}
END {print "</bugzilla>"}
实际的CSV文件是:
cf_foo,cf_bar,short_desc,cf_zebra,cf_pizza,cf_dumpling ,assigned_to,bug_status,cf_word,cf_caslte
ABCD,A-BAR-0032,A NICE DESCRIPTION - help me,pretty,Pepperoni,,,NEW,,
实际输出是:
$ awk -f csvtobugs.awk bugs.csv
<bugzilla version="3.4.1" urlbase="http://mozilla.com/" maintainer="somebody@mozilla.com" exporter="somebody.else@mozilla.com">
<bug>
<cf_foo,cf_bar,short_desc,cf_zebra,cf_pizza,cf_dumpling>ABCD,A-BAR-0032,A</cf_foo,cf_bar,short_desc,cf_zebra,cf_pizza,cf_dumpling>
<,assigned_to,bug_status,cf_word,cf_caslte>NICE</,assigned_to,bug_status,cf_word,cf_caslte>
<>DESCRIPTION</>
<>-</>
<>help</>
<>me,pretty,Pepperoni,,,NEW,,</>
</bug>
<bug>
</bug>
</bugzilla>
显然,不是预期的结果(我承认,我从这个论坛复制粘贴了这个脚本:http://www.unix.com/shell-programming-scripting/21404-csv-xml.html)。问题是,自从我查看awk脚本以来,它已经很久了,而且我没有IDEA语法意味着什么。
答案 0 :(得分:4)
您需要在FS = ","
规则中设置BEGIN
以使用逗号作为字段分隔符;如果字段分隔符是一个选项卡,则显示它的代码应该有效,这是一个不同的(也是流行的)常规文件,通常仍被称为“CSV”,即使不使用逗号; - )。
答案 1 :(得分:1)
使用您知道的工具:)
awk脚本看起来不会处理“和其他CSV奇怪。(我认为它只是在选项卡上分裂 - 因为其他答案注意它需要更改为拆分,)python,perl .Net等有对象要完全处理CSV和XML,可能你可以用awk脚本中的字符编写解决方案,更重要的是要理解它。
答案 2 :(得分:1)
请记住,在获得以下方案之前,在csv中使用逗号分割是正常的:
1997,Ford,E350,"Super, luxurious truck"
在这种情况下,它会将“超级豪华卡车”分成两个不正确的项目。我建议在另一种语言中使用csv libs,如上面帖子中的“Mark”所述。
答案 3 :(得分:0)
我能够通过更改FS(字段分隔符)来修复它:
BEGIN {
FS=",";
OFS = "\n"}
NR == 1 {for (i = 1; i <=NF; i++)
tag[i]=$i
print "<bugzilla version=\"3.4.1\" urlbase=\"http://mozilla.com/\" maintainer=\"somebody@mozilla.com\" exporter=\"somebody.else@mozilla.com\">"}
NR != 1 {print " <bug>"
for (i = 1; i <= NF; i++)
print " <" tag[i] ">" $i "</" tag[i] ">"
print " </bug>"}
END {print "</bugzilla>"}
输出:
<bugzilla version="3.4.1" urlbase="http://mozilla.com/" maintainer="somebody@mozilla.com" exporter="somebody.else@mozilla.com">
<bug>
<cf_foo>ABCD</cf_foo>
<cf_bar>A-BAR-0032</cf_bar>
<short_desc>A NICE DESCRIPTION - help me</short_desc>
<cf_zebra>pretty</cf_zebra>
<cf_pizza>Pepperoni</cf_pizza>
<cf_dumpling ></cf_dumpling >
<assigned_to></assigned_to>
<bug_status>NEW</bug_status>
<cf_word></cf_word>
<cf_caslte></cf_caslte>
</bug>
</bugzilla>
答案 4 :(得分:0)
您可以使用各种技巧,例如设置FS。在Awk新闻组中可以找到更多技巧。还有像我这样的解析器:http://lorance.freeshell.org/csv/
答案 5 :(得分:0)
您可以尝试我的csvprintf。它可以将CSV转换为XML,然后您可以根据需要使用XSLT设置样式。