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

为列数不固定的表格添加分数列的Shell脚本优化方案

优化CSV数据匹配脚本(大数据量场景)

需求背景

现有两个CSV文件:

  1. 1.csv:存储姓名与分数的对应关系,格式如下:
name,score
Alice,6
Bob,1
Joe,2
John,7
Michel,9
  1. 2.csv:列数不固定的姓名表格(列数可为1、2、3等),格式如下:
Alice, Bob,
Michel,
Joe,John

需要实现的效果:在2.csv的每个姓名右侧添加对应的分数列,期望输出:

Alice,6,Bob,1
Michel,9
Joe,2,John,7

现有脚本问题

此前尝试的Shell脚本在小数据量下可正常运行,但处理大数据量时性能失效,脚本代码如下:

#!/bin/bash

declare -A scores
while IFS=',' read -r name score
do
    scores["$name"]=$score
done < 1.csv

while IFS=',' read -r -a names
do
    for name in "${names[@]}"
    do
        name=$(echo "$name" | xargs)
        echo -n "$name,${scores[$name]},"
    done
    echo
done < 2.csv

优化方案(AWK实现)

AWK专为文本结构化数据处理设计,无需依赖Shell循环和外部子进程调用,执行效率远高于原生Shell脚本,适合大数据量场景:

#!/usr/bin/awk -f

# 处理第一个文件1.csv,构建姓名-分数映射字典
NR == FNR {
    # 跳过表头行
    if (NR == 1) next
    # 提取并清理姓名(去除前后空格)
    name = $0
    sub(/^[[:space:]]*/, "", name)
    sub(/[[:space:]]*,.*$/, "", name)
    # 提取并清理分数
    score = $0
    sub(/^.*,/, "", score)
    sub(/[[:space:]]*$/, "", score)
    scores[name] = score
    next
}

# 处理第二个文件2.csv
{
    # 按逗号分割当前行所有字段
    n = split($0, fields, /,/)
    output = ""
    for (i = 1; i <= n; i++) {
        # 清理姓名字段的所有空格
        name = fields[i]
        gsub(/[[:space:]]+/, "", name)
        # 非空姓名才拼接输出内容
        if (name != "") {
            output = output (output != "" ? "," : "") name "," scores[name]
        }
    }
    # 打印处理后的行
    print output
}

使用步骤

  1. 将上述代码保存为map_score.awk
  2. 赋予执行权限:chmod +x map_score.awk
  3. 运行脚本:./map_score.awk 1.csv 2.csv

性能优势说明

  • 避免了Shell脚本中频繁的子进程调用(如echo "$name" | xargs会反复创建子进程,大数据量下严重拖慢速度)
  • AWK内置函数为原生实现,处理速度远快于Shell循环
  • 内存使用更高效,姓名-分数映射直接在AWK内存中处理,无Shell关联数组的额外开销

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 14:41:08