如何合并152000个递归CSV文件至单文件并避免同名覆盖
解决CSV文件合并/安全移动的实用方案
针对你有152000个深层目录下的CSV文件、重名文件易被覆盖的问题,这里提供两个贴合需求的方案:
方案一:直接合并所有CSV(无需移动文件)
这个方案跳过文件移动步骤,直接遍历所有CSV完成合并,既避免了覆盖风险,还能灵活处理表头和数据来源追踪,效率更高。
1. 带文件路径标识的合并(方便追踪数据来源)
如果需要明确每段数据来自哪个文件,可以在每个文件内容前加上路径标记:
find . -name "*.csv" -exec sh -c 'for file do echo "=== 来源文件:$file ==="; cat "$file"; done' sh {} + > final.csv
2. 跳过重复表头的合并(适合CSV结构一致的场景)
如果所有CSV都有相同的表头,合并时只保留第一个文件的表头,其余文件自动跳过第一行:
# 初始化标记变量,用于识别第一个文件 first_file="" # 遍历所有CSV(sort可选,用来按路径排序合并顺序) find . -name "*.csv" | sort | while read -r file; do if [ -z "$first_file" ]; then # 第一个文件完整写入 cat "$file" first_file="done" else # 后续文件跳过第一行表头 tail -n +2 "$file" fi done > final.csv
方案二:安全移动所有CSV到同一目录(不覆盖重名文件)
如果你需要把所有CSV集中到一个目录方便后续操作,可以用以下两种方式实现安全移动,重名文件会被自动重命名:
1. 用rsync快速移动(推荐,适合大量文件)
rsync自带备份重命名功能,处理海量文件效率极高:
# 创建目标目录 mkdir -p all_csvs # 移动所有CSV到目标目录,重名文件自动添加时间戳后缀 rsync -av \ --include="*.csv" \ --exclude="*" \ --remove-source-files \ --backup \ --suffix="_$(date +%Y%m%d_%H%M%S)" \ ./ ./all_csvs/
参数说明:
--include="*.csv":只处理CSV文件--exclude="*":排除所有非CSV文件--remove-source-files:移动后删除源文件(不需要删除可去掉此参数)--backup --suffix=...:给重名文件添加唯一时间戳后缀,彻底避免覆盖
2. 自定义脚本重命名移动(灵活控制后缀规则)
如果想要用数字序号作为重名后缀(比如zoo_1.csv、zoo_2.csv),可以用shell脚本实现:
# 创建目标目录 mkdir -p all_csvs # 遍历所有CSV文件 find . -name "*.csv" -type f | while read -r file; do # 获取纯文件名(不含路径) filename=$(basename "$file") # 初始目标路径 dest="./all_csvs/$filename" # 如果目标文件已存在,循环添加数字后缀 counter=1 while [ -f "$dest" ]; do # 生成新文件名:原文件名去后缀 + _序号 + .csv dest="./all_csvs/$(basename "$file" .csv)_$counter.csv" counter=$((counter + 1)) done # 执行移动 mv "$file" "$dest" done
移动完成后合并
集中到统一目录后,可使用优化后的合并命令处理表头:
cd all_csvs first_file=1 for file in *.csv; do if [ $first_file -eq 1 ]; then cat "$file" > final.csv first_file=0 else tail -n +2 "$file" >> final.csv fi done
内容的提问来源于stack exchange,提问作者Amit Singh
相关产品推荐
相关产品推荐

