You need to enable JavaScript to run this app. 如何用Bash脚本分割大CSV文件,确保同日期数据不被拆分到多文件
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bash脚本分割大CSV文件,确保同日期数据不被拆分到多文件

实现思路
  • 先对所有CSV内容做预处理,统计每个日期对应的总行数,同时输出所有去重后的日期列表
  • 采用贪心分配规则:依次将每个日期分配到当前总行数最小的分组,既保证同一日期所有行归属同一个文件,也能让各分割文件的行数尽可能接近
  • 最后遍历所有数据行,按日期对应的分组编号写入对应文件,所有输出文件会先统一写入表头
完整可运行脚本
#!/bin/bash
VERSION=$1
# 分割份数默认取CPU核心数,也可通过第二个参数手动指定
NPROC=${2:-$(nproc)}
INPUT_FILES="${VERSION}_*.csv"

# 第一步:给所有输出文件写入表头
head -n1 $(ls $INPUT_FILES | head -n1) | awk -v n="$NPROC" '{
    for(i=0;i<n;i++) print $0 > "part_"i".csv"
}'

# 第二步:统计每个日期的行数,同时生成日期分配规则
awk -F';' '
FNR==1 {next} # 跳过所有文件的表头
{
    cnt[$1]++ # 第一列是DATE,统计每个日期的行数
}
END {
    nproc = '"$NPROC"'
    # 初始化每个分组的当前总负载
    for(i=0;i<nproc;i++) group_load[i] = 0
    # 遍历所有日期,贪心分配到负载最小的分组
    for(date in cnt) {
        min_load = group_load[0]
        min_idx = 0
        for(i=1;i<nproc;i++) {
            if(group_load[i] < min_load) {
                min_load = group_load[i]
                min_idx = i
            }
        }
        date_group[date] = min_idx
        group_load[min_idx] += cnt[date]
    }
    # 输出日期到分组的映射规则
    for(date in date_group) print date "\t" date_group[date]
}
' $INPUT_FILES > date_group_map.tmp

# 第三步:根据映射规则,把所有数据行写入对应分组文件
awk -F';' '
FNR==1 {next} # 跳过表头
NR==FNR {
    # 先加载日期分组映射
    date_group[$1] = $2
    next
}
{
    # 按日期找对应分组,写入文件
    outfile = "part_" date_group[$1] ".csv"
    print $0 >> outfile
}
' date_group_map.tmp $INPUT_FILES

# 清理临时文件
rm date_group_map.tmp
使用说明
  • 执行方式:./split.sh [版本号] [可选:分割份数],比如./split.sh v1默认按CPU核心数分割,./split.sh v2 12指定分割为12份
  • 脚本默认CSV字段分隔符为分号;,如果是逗号分隔的CSV,把两处-F';'修改为-F','即可
  • 分割后的文件命名为part_0.csv到part_{N-1}.csv,都自带表头,同一日期的所有行都会在同一个文件中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 03:27:03