如何垂直分割含重复列的CSV文件?命令行及Python实现方法
当然可以解决这个需求!我分两种方案给你讲:命令行工具实现,以及更通用的Python脚本实现,你可以根据自己的场景选择~
命令行方案(适用于无嵌套逗号的简单CSV)
如果你的CSV里没有带逗号的单元格(比如"123 Main St, Apt 4B"这种格式),用awk就能快速按列分割,非常高效。
手动指定列分割
假设你的原CSV文件是data.csv,表头是id,site,address,site,address,site,address,要生成3个分别包含id+site+address的文件,直接执行以下命令:
# 第一个文件:id + 第一组site、address awk -F ',' '{print $1","$2","$3}' data.csv > output1.csv # 第二个文件:id + 第二组site、address awk -F ',' '{print $1","$4","$5}' data.csv > output2.csv # 第三个文件:id + 第三组site、address awk -F ',' '{print $1","$6","$7}' data.csv > output3.csv
通用循环脚本(适合多组重复列)
如果重复的列组很多,手动写命令太麻烦,可以用循环批量生成:
# 定义每组的列数(这里是2列:site+address) GROUP_SIZE=2 # 总组数 NUM_GROUPS=3 # 保留的标识列(这里是第1列id) KEEP_COL=1 for i in $(seq 1 $NUM_GROUPS); do # 计算当前组的起始列和结束列 START_COL=$((KEEP_COL + 1 + (i-1)*GROUP_SIZE)) END_COL=$((START_COL + GROUP_SIZE - 1)) # 生成对应文件 awk -F ',' -v s="$START_COL" -v e="$END_COL" -v k="$KEEP_COL" '{print $k","$s","$e}' data.csv > output_$i.csv done
注意:如果你的CSV存在带逗号的单元格(用引号包裹的那种),awk的默认分割逻辑会出错,这时候建议用下面的Python方案。
Python方案(适用于所有CSV场景)
Python的CSV处理库能完美处理各种复杂格式(包括带引号的嵌套逗号),这里提供两种实现方式:
原生csv模块实现(无第三方依赖)
不需要安装额外库,用Python自带的csv模块就能完成,兼容性拉满:
import csv # 配置参数 INPUT_FILE = "input.csv" GROUP_SIZE = 2 # 每组的列数(site+address是2列) NUM_GROUPS = 3 # 总共有3组重复列 KEEP_COL_INDEX = 0 # 要保留的标识列索引(这里是第1列id) # 打开输入文件 with open(INPUT_FILE, 'r', newline='', encoding='utf-8') as infile: reader = csv.reader(infile) headers = next(reader) # 获取表头 # 初始化所有输出文件和写入器 output_files = [] writers = [] for group_idx in range(NUM_GROUPS): # 生成输出文件名 out_filename = f"output_group_{group_idx+1}.csv" outfile = open(out_filename, 'w', newline='', encoding='utf-8') output_files.append(outfile) writer = csv.writer(outfile) # 写入新表头:标识列 + 当前组的列名 group_start = KEEP_COL_INDEX + 1 + group_idx * GROUP_SIZE group_headers = [headers[KEEP_COL_INDEX]] + headers[group_start:group_start+GROUP_SIZE] writer.writerow(group_headers) writers.append(writer) # 逐行处理数据并写入对应文件 for row in reader: for group_idx in range(NUM_GROUPS): group_start = KEEP_COL_INDEX + 1 + group_idx * GROUP_SIZE # 提取标识列 + 当前组的列数据 new_row = [row[KEEP_COL_INDEX]] + row[group_start:group_start+GROUP_SIZE] writers[group_idx].writerow(new_row) # 关闭所有输出文件 for f in output_files: f.close()
pandas实现(简洁高效)
如果你已经安装了pandas(数据分析常用库),代码会更简洁,处理大文件也更高效:
import pandas as pd # 读取原CSV df = pd.read_csv("input.csv") # 配置参数 GROUP_SIZE = 2 NUM_GROUPS = 3 KEEP_COL_NAME = "id" # 要保留的标识列名 # 循环生成每个分组的CSV for group_idx in range(NUM_GROUPS): # 计算当前组的列范围 start_col = 1 + group_idx * GROUP_SIZE end_col = start_col + GROUP_SIZE # 提取子DataFrame:标识列 + 当前组的列 sub_df = df[[KEEP_COL_NAME] + list(df.columns[start_col:end_col])] # 保存为新CSV(index=False表示不保存行索引) sub_df.to_csv(f"output_pandas_group_{group_idx+1}.csv", index=False)
执行完脚本后,你就能得到3个分别包含一组site+address的CSV文件啦~
内容的提问来源于stack exchange,提问作者Amit Sharma
相关产品推荐
相关产品推荐

