You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Awk将同组键值对多行数据聚合转换为CSV格式?

使用Awk将键值对行流聚合为CSV格式

针对这种每行包含多组「字段名 字段值」的行流数据,我们可以用Awk编写脚本自动聚合同一主体的分散数据,转换为标准CSV格式。以下是具体实现方案:

完整Awk脚本

BEGIN {
    OFS = ","
    field_idx = 0
}

# 解析每行的键值对,处理带引号的字段
{
    i = 1
    curr_key = ""
    curr_val = ""
    rec_id = ""
    while (i <= NF) {
        # 处理带引号的字段(字段名或值含空格的情况)
        if ($i ~ /^"/) {
            quoted_str = $i
            i++
            while (i <= NF && $i !~ /"$/) {
                quoted_str = quoted_str " " $i
                i++
            }
            quoted_str = quoted_str " " $i
            gsub(/^"|"$/, "", quoted_str)  # 移除首尾引号
            if (curr_key == "") {
                curr_key = quoted_str
            } else {
                curr_val = quoted_str
            }
        } else {
            # 处理普通无引号字段
            if (curr_key == "") {
                curr_key = $i
            } else {
                curr_val = $i
            }
        }

        # 键值对完整时,存储数据
        if (curr_key != "" && curr_val != "") {
            # 记录所有字段名,去重并按出现顺序保存
            if (!(curr_key in field_map)) {
                field_map[curr_key] = ++field_idx
                fields[field_idx] = curr_key
            }
            # 生成聚合用的唯一记录ID(这里用Company+Name组合,确保同一人/主体的行被聚合)
            if (curr_key == "Company") {
                rec_id = curr_val
            } else if (curr_key == "Name") {
                rec_id = rec_id "|" curr_val
            }
            # 保存当前键值对到对应记录
            data[rec_id, curr_key] = curr_val
            # 重置临时变量
            curr_key = ""
            curr_val = ""
        }
        i++
    }
    # 记录唯一的记录ID,避免重复输出
    if (rec_id != "" && !(rec_id in rec_map)) {
        rec_map[rec_id] = 1
        rec_list[++rec_cnt] = rec_id
    }
}

END {
    # 输出CSV表头
    for (i = 1; i <= field_idx; i++) {
        # 含空格的字段名用引号包裹,符合CSV规范
        printf "%s%s", (fields[i] ~ / / ? "\"" fields[i] "\"" : fields[i]), (i < field_idx ? OFS : "\n")
    }
    # 输出每条聚合后的记录
    for (r = 1; r <= rec_cnt; r++) {
        rec_id = rec_list[r]
        for (i = 1; i <= field_idx; i++) {
            field = fields[i]
            val = data[rec_id, field]
            # 含空格的字段值用引号包裹
            printf "%s%s", (val ~ / / ? "\"" val "\"" : val), (i < field_idx ? OFS : "\n")
        }
    }
}

使用方法

  1. 将上述脚本保存为aggregate_to_csv.awk文件。
  2. 假设输入数据文件名为input.txt,执行以下命令生成CSV:
awk -f aggregate_to_csv.awk input.txt > output.csv

脚本关键逻辑说明

  • 字段解析:专门处理带引号的字段(比如"Favorite Book"或"The Hobbit"),确保含空格的字段名/值被正确识别,不会被空格分割成多个部分。
  • 聚合依据:用Company和Name的组合作为唯一记录ID,确保同一主体的分散行数据被聚合到同一行。如果需要调整聚合规则,修改生成rec_id的逻辑即可。
  • CSV规范兼容:自动为含空格的字段名/值添加双引号,符合标准CSV格式要求。
  • 动态表头:自动收集所有出现过的字段名作为表头,无需预先指定字段列表。

运行后,你提供的示例输入会生成目标格式的CSV文件。

内容的提问来源于stack exchange,提问作者user3310334

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:14:52