AWK for循环批量按第四列匹配合并同前缀文件报错修复
问题根因
原代码运行异常由3个核心逻辑错误导致:
- 文件名配对逻辑硬编码:
f2="${f1/-1/-3}"仅做简单字符串替换,默认-1开头的文件对应的-3开头文件除了1和3的位置外其余字符完全一致,无法适配C组(C-111.txt对应C-312.txt)、D组(D-112.txt对应D-311.txt)这类后缀数字不匹配的分组,直接触发文件不存在报错。 - 通配符匹配逻辑粗糙:
*-1**.txt的匹配规则没有绑定短横杠后的位置,容易误抓不符合分组规则的文件。 - 变量引用不规范:
$f1_merged.txt没有给变量加边界,shell会将f1_merged识别为完整变量名,导致输出文件名异常。 - awk数组键冗余:
a[$4,$4]属于无意义的重复键定义,单键$4即可实现第4列匹配的需求,冗余写法不会提升匹配准确性。
修正后可直接运行的代码
# 提取所有txt文件的前缀(短横杠前的字符),去重后逐组处理 for prefix in $(ls *.txt | awk -F'-' '{print $1}' | uniq); do # 自动匹配当前前缀下编号以1开头的文件 f1=$(compgen -G "${prefix}-1*.txt") # 自动匹配当前前缀下编号以3开头的文件 f2=$(compgen -G "${prefix}-3*.txt") # 两个配对文件都存在时才执行合并,避免空文件报错 if [[ -f "$f1" && -f "$f2" ]]; then awk -F'\t' ' BEGIN { OFS = FS } NR == FNR { # 以第4列(db_SNP)为键,存储第一个文件的整行内容 snp_map[$4] = $0 next } # 第二个文件中第4列匹配到已存键值时,拼接两行输出 $4 in snp_map { print snp_map[$4], $0 } ' "$f1" "$f2" > "${prefix}_merged.txt" fi done
代码适配说明
- 分组逻辑完全按前缀匹配,自动识别同前缀下的1开头、3开头文件,不管两个文件横杠后其余数字是否一致,都能正确配对,适配给出的A、B、C、D所有分组场景。
- 加了文件存在性校验,某组缺失配对文件时不会抛出awk读取错误,直接跳过处理。
- 匹配逻辑遍历两个文件所有行,以第4列SNPID为唯一匹配键,输出结果和给出的A组预期完全一致。
- 输出文件统一命名为
[前缀]_merged.txt,比如A组结果写入A_merged.txt,不会出现文件名解析异常。
内容的提问来源于stack exchange,提问作者Milos
相关产品推荐
相关产品推荐

