不同目录下同名文件最后一列横向合并脚本问题求助
批量合并多目录下同名文件的指定列
问题需求
遍历800个子目录,提取每个目录中myfile.txt文件的最后一列,将这些列横向合并后输出到单个文件中。
示例文件
dir_1/myfile.txt
Row1 44.4 Row2 45.5 Row3 46.2 Row4 46.3
dir_2/myfile.txt
Row1 33.7 Row2 25.8 Row3 14.9 Row4 32.1
dir_3/myfile.txt
Row1 12.1 Row2 13.2 Row3 14.5 Row4 16.4
现有脚本问题
使用以下awk脚本后,输出不符合预期:
BEGIN { OFS="\t" } { lines[FNR]= lines[FNR] (FNR==NR ? "" : OFS) $2 } END { for (i=1; i<=FNR; i++) print lines[i] }
执行命令:
awk '...' dir_*/myfile.txt > out.txt
错误输出
44.4 45.5 46.2 46.3 33.7 25.8 14.9 32.1 32.1 12.1 13.2 14.5
预期输出
44.4 33.7 12.1 45.5 25.8 13.2 46.2 14.9 14.5 46.3 32.1 16.4
问题原因与修正方案
原脚本逻辑本身是正确的,但错误输出大概率是因为部分文件行数不一致(比如某个文件多了冗余行),或者文件采用Windows格式换行符(\r\n),导致字段处理异常。
方案1:兼容行数不一致的健壮脚本
该脚本会自动以所有文件中的最小行数为准进行合并,避免行数差异导致的输出混乱:
BEGIN { OFS="\t" } # 记录每个文件的总行数 FILENAME != prevfile { prevfile = FILENAME file_count++ if (FNR > 1) file_lines[file_count-1] = FNR - 1 } # 仅处理所有文件都存在的行号 FNR <= min_lines || file_count == 1 { lines[FNR] = lines[FNR] (lines[FNR] == "" ? "" : OFS) $2 } END { # 补充记录最后一个文件的行数 file_lines[file_count] = FNR # 计算所有文件的最小行数 min_lines = file_lines[1] for (i=2; i<=file_count; i++) { if (file_lines[i] < min_lines) min_lines = file_lines[i] } # 输出合并结果 for (i=1; i<=min_lines; i++) { print lines[i] } }
方案2:简化脚本(适用于所有文件行数完全一致的场景)
同时处理Windows格式换行符的问题:
BEGIN { OFS="\t" } # 去除字段末尾的回车符,兼容Windows格式文件 { sub(/\r$/, "", $2) } { lines[FNR] = lines[FNR] (FNR==NR ? "" : OFS) $2 } END { for (i=1; i<=length(lines); i++) { print lines[i] } }
执行修正后的脚本命令:
awk -f merge_cols.awk dir_*/myfile.txt > out.txt
验证结果
运行修正后的脚本后,将得到符合预期的横向合并输出。
内容的提问来源于stack exchange,提问作者EverLearner
相关产品推荐
相关产品推荐

