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

Unix下拆分CSV文件:避免首列相同行被分割

如何按首列分组拆分大CSV文件(避免同组行拆分到不同文件)

你的需求很明确:处理已排序的超大CSV(7GB、1亿行),拆分时要保证首列值相同的行始终在同一个文件里,不能像split那样硬按行数/大小切割。确实,awk是解决这类问题的最佳工具,它能高效处理大文件,同时灵活控制分组逻辑。

核心思路

因为你的CSV已经按首列排序,所以相同首列的行是连续的。我们只需要跟踪当前输出文件的行数/大小,当新增行超过预设阈值时,检查当前行的首列是否和上一行一致:

  • 如果不一致:切换到新文件
  • 如果一致:继续写入当前文件,避免拆分同组数据

方案1:按行数拆分(约100K行/文件)

下面的awk脚本会把文件拆分成最多100K行/文件,但会确保同首列的行不被拆分:

BEGIN {
    # 设置目标行数,可根据需求调整
    target_lines = 100000
    file_num = 0
    current_lines = 0
    prev_key = ""
    # 打印进度到stderr,避免和输出文件内容混淆
    printf "Creating output file x%05d\n", file_num > "/dev/stderr"
    out_file = sprintf("x%05d", file_num)
}

# 按逗号分隔提取首列
{
    current_key = $1
    # 检查是否需要切换文件:当前行数+1超过阈值,且当前行首列和上一行不同
    if (current_lines + 1 > target_lines && current_key != prev_key) {
        file_num++
        current_lines = 0
        printf "Creating output file x%05d\n", file_num > "/dev/stderr"
        out_file = sprintf("x%05d", file_num)
    }
    # 写入当前行到输出文件
    print >> out_file
    current_lines++
    prev_key = current_key
}

END {
    printf "拆分完成,共创建 %d 个文件\n", file_num + 1 > "/dev/stderr"
}

使用方法

  1. 把上面的脚本保存为split_csv_by_lines.awk
  2. 运行命令:
awk -F ',' -f split_csv_by_lines.awk your_large_file.csv

方案2:按文件大小拆分(约6MB/文件)

如果更倾向于按文件大小拆分,下面的脚本会把文件拆分成最多6MB/文件,同样保证同首列行不拆分:

BEGIN {
    # 设置目标大小(6MB,可根据需求调整)
    target_size = 6 * 1024 * 1024
    file_num = 0
    current_size = 0
    prev_key = ""
    printf "Creating output file x%05d\n", file_num > "/dev/stderr"
    out_file = sprintf("x%05d", file_num)
}

{
    current_key = $1
    # 计算当前行的大小(包含换行符)
    line_size = length($0) + 1
    # 检查是否需要切换文件:当前大小+当前行大小超过阈值,且当前行首列和上一行不同
    if (current_size + line_size > target_size && current_key != prev_key) {
        file_num++
        current_size = 0
        printf "Creating output file x%05d\n", file_num > "/dev/stderr"
        out_file = sprintf("x%05d", file_num)
    }
    print >> out_file
    current_size += line_size
    prev_key = current_key
}

END {
    printf "拆分完成,共创建 %d 个文件\n", file_num + 1 > "/dev/stderr"
}

使用方法

  1. 保存为split_csv_by_size.awk
  2. 运行命令:
awk -F ',' -f split_csv_by_size.awk your_large_file.csv

关键注意事项

  1. 必须保证CSV已排序:脚本依赖首列相同的行连续排列,否则会出现同首列行被拆分的情况。你已经说明文件是排序好的,所以没问题。
  2. 高效处理大文件:awk是原生编译的工具,处理7GB级别的文件速度很快,不会像Python等脚本语言那样出现内存瓶颈。
  3. 文件名格式:输出文件名是x00000、x00001...和你预期的格式完全一致。
  4. 进度可见:脚本会把创建文件的进度打印到标准错误流(stderr),你可以实时看到拆分进度,不会干扰输出文件内容。

测试验证

用你提供的示例数据测试(把target_lines改成2),脚本会生成3个文件,完全符合你的预期结果:

  • x00000:包含3行AABB1122的记录
  • x00001:包含2行CCDD4444的记录
  • x00002:包含CCEE4444和DDFF9900的所有记录

内容的提问来源于stack exchange,提问作者17th Lvl Botanist

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:48:47