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

合并不同长度的多个CSV文件及Perl脚本适配方案咨询

适配不同长度CSV文件的合并方案(Perl脚本修改+其他方法)

嘿,这个问题我太熟了!合并不同行数量的CSV核心就是要处理「某文件已经读完但其他文件还有内容」的情况,得给缺失的行补上对应数量的空字段,保证最终的CSV格式合规。下面分Perl脚本修改和几个更省心的替代方法来讲:

一、修改原Perl脚本适配不同长度CSV

假设你原来的Perl脚本是同步逐行读取多个文件的方式,这种方式在文件长度不一致时会提前终止。我们改成先把所有文件内容预读到内存,再按最长文件的行数逐行拼接,同时处理缺失行的空字段填充:

修改后的Perl脚本示例

#!/usr/bin/perl
use strict;
use warnings;

# 替换成你要合并的CSV文件列表
my @files = qw(file1.csv file2.csv file3.csv);
my @file_data;
my $max_rows = 0;

# 第一步:读取所有文件的内容,记录每个文件的行数和总行数最大值
foreach my $file (@files) {
    open my $fh, '<', $file or die "打不开文件 $file: $!";
    my @lines = <$fh>;
    chomp @lines;
    close $fh;
    push @file_data, \@lines;
    $max_rows = scalar @lines if scalar @lines > $max_rows;
}

# 第二步:输出表头(默认所有文件表头一致,取第一个文件的表头)
print $file_data[0][0], "\n";

# 第三步:逐行合并,缺失行补对应数量的空字段
for my $row_idx (1..$max_rows-1) {  # 跳过表头,从数据行开始
    my @merged_fields;
    foreach my $data (@file_data) {
        if ($row_idx < scalar @$data) {
            # 当前文件有这一行,直接拆分字段
            push @merged_fields, split /,/, $data->[$row_idx];
        } else {
            # 当前文件无此行,按表头字段数补空
            my $field_count = scalar split /,/, $file_data[0][0];
            push @merged_fields, ('') x $field_count;
        }
    }
    print join(',', @merged_fields), "\n";
}

关键修改说明

  • 预读取所有内容:不再同步逐行读,而是把每个文件的所有行存到数组里,这样能明确知道每个文件的总行数。
  • 空字段精准填充:当某个文件行数不足时,根据表头的字段数量填充对应个数的空字符串,避免CSV格式错乱。
  • 如果你要处理带逗号的复杂字段(比如用引号包裹的"张三,男"),上面的split /,/会出错,建议用Perl的Text::CSV模块(先通过cpan Text::CSV安装),用$csv->getline($fh)来读取行,拆分字段更严谨。

二、其他更简便的实现方法

如果不想折腾Perl脚本,这些方案可能更省心:

1. Python + Pandas(最推荐,处理复杂场景稳得一批)

Pandas会自动对齐表头,不同长度的文件缺失行自动填充NaN,你可以一键转成空字符串:

import pandas as pd
import glob

# 获取当前目录下所有CSV文件
csv_files = glob.glob('*.csv')
# 批量读取所有CSV并合并
df_list = [pd.read_csv(file) for file in csv_files]
merged_df = pd.concat(df_list, ignore_index=True)
# 把缺失值替换为空字符串,保存为新CSV
merged_df.fillna('', inplace=True)
merged_df.to_csv('merged.csv', index=False)

这个方法不用手动处理字段数、行长度,甚至带引号的复杂字段也能完美识别。

2. Awk命令行工具(适合快速处理简单CSV)

用Awk记录每个文件的行,然后遍历到最长行数,自动补空字段:

BEGIN {
    file_count = ARGC - 1
    # 读取所有文件的行到数组
    for (i=1; i<=file_count; i++) {
        while ((getline line < ARGV[i]) > 0) {
            file_lines[i][++line_count[i]] = line
        }
        close(ARGV[i])
        max_rows = (line_count[i] > max_rows) ? line_count[i] : max_rows
    }
    # 输出表头
    print file_lines[1][1]
    # 逐行合并
    for (row=2; row<=max_rows; row++) {
        merged = ""
        for (i=1; i<=file_count; i++) {
            if (row <= line_count[i]) {
                merged = merged (merged == "" ? "" : ",") file_lines[i][row]
            } else {
                # 按表头字段数补空
                split(file_lines[1][1], fields, ",")
                empty = ""
                for (f=1; f<=length(fields); f++) {
                    empty = empty (f==1 ? "" : ",") ""
                }
                merged = merged (merged == "" ? "" : ",") empty
            }
        }
        print merged
    }
}

使用方式:把上面的代码存成merge_csv.awk,然后执行awk -f merge_csv.awk file1.csv file2.csv > merged.csv

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:25:12