我找到了以下用于将包含键值信息的文件转换为 CSV 文件的 bash 脚本:
awk -F ":" -v OFS="," '
BEGIN { print "category","recommenderSubtype", "resource", "matchesPattern", "resource", "value" }
function printline() {
print data["category"], data["recommenderSubtype"], data["resource"], data["matchesPattern"], data["resource"], data["value"]
}
{data[$1] = $2}
NF == 0 {printline(); delete data}
END {printline()}
' file.yaml
但是执行后,它只转换第一组数据(只转换前6行数据),像这样
category,recommenderSubtype,resource,matchesPattern,resource,value
COST,CHANGE_MACHINE_TYPE,instance-1,f1-micro,instance-1,g1-small
我的原始文件是这样的(1000行以上):
category:COST
recommenderSubtype:CHANGE_MACHINE_TYPE
resource:portal-1
matchesPattern:f1-micro
resource:portal-1
value:g1-small
category:PERFORMANCE
recommenderSubtype:CHANGE_MACHINE_TYPE
resource:old-3
matchesPattern:n1-standard-4
resource:old-3
value:n1-highmem-2
我是否缺少任何命令?
最佳答案
原始脚本的问题是这些行:
NF == 0 {printline(); delete data}
END {printline()}
第一行意思是:如果当前行没有记录就调用printline()。第二行表示在处理完所有数据后调用printline()
。
输入数据格式的困难在于它并不能很好地指示何时输出下一条记录。下面,我只是将脚本更改为每 6 条记录输出一次数据。如果可能存在重复键,输出标准可能是“所有字段已填充”或需要稍微不同编程的标准。
#!/bin/sh -e
awk -F ":" -v OFS="," '
BEGIN {
records_in = 0
print "category","recommenderSubtype", "resource", "matchesPattern", "resource", "value"
}
{
data[$1] = $2
records_in++
if(records_in == 6) {
records_in = 0;
print data["category"], data["recommenderSubtype"], data["resource"], data["matchesPattern"], data["resource"], data["value"]
}
}
' file.yaml
其他表扬
- 我刚刚删除了
delete
语句,因为我不确定它的作用。awk
的 POSIX 规范仅将其定义为删除单个数组元素。如果要删除整个数组,建议对元素进行循环。但是,如果所有字段始终存在,则不妨完全消除它。 - 欢迎来到 SO(我也是新来的)。下次你问的时候,我建议将问题标记为
awk
而不是bash
因为 AWK 实际上是这个问题中使用bash
的脚本语言只负责用合适的参数调用awk
:)
关于linux - 转换 key :value to CSV file,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58597307/