对比两文件列并为file1无匹配记录添加dev标记的awk实现
问题解决:调整awk脚本处理匹配与无匹配记录的对比需求
需求说明
需要处理压缩文件file1.gz和文本文件file2,规则如下:
- 用
file1的$1、$2字段匹配file2的$1、$2字段,找到对应file2的$5字段值 - 对
file1中第4、6……隔列的每个字符,与file2的$5值对比:匹配则追加ref,不匹配则追加dev - 若
file1的行在file2中无对应记录,该行所有对比结果均追加dev
原awk脚本仅处理了有匹配的记录,需调整以覆盖所有场景。
原始文件内容
file1.gz内容
NC_044998.1 4013 0 TT 2 GG 0 TT 0 TT 0 TT NC_044998.1 4016 0 TT 0 TT 0 TT 2 GG 0 TT NC_044998.1 4017 0 TT 0 TT 0 TT 0 TT 0 TT NC_044998.1 4018 0 TT 0 TA 0 TT 0 TT 0 TT NC_044998.1 4019 2 CC 2 CC 2 CC 2 CC 2 CC
file2内容
chromo position major minor ref anc knownEM nInd NC_044998.1 4013 T G T T 0.000000 1 NC_044998.1 4016 G T G G 0.000000 1 NC_044998.1 4018 T A T T 0.000000 1 NC_044998.1 4019 G A G G 0.000000 1 NC_044998.1 3760 G A G G 0.000000 1
期望输出
NC_044998.1 4013 0 TT 2 GG 0 TT 0 TT 0 TT ref ref dev dev ref ref ref ref ref ref NC_044998.1 4016 0 TT 0 TT 0 TT 2 GG 0 TT dev dev dev dev dev dev ref ref dev dev NC_044998.1 4017 0 TT 0 TT 0 TT 0 TT 0 TT dev dev dev dev dev dev dev dev dev dev NC_044998.1 4018 0 TT 0 TA 0 TT 0 TT 0 TT ref ref ref dev ref ref ref ref ref ref NC_044998.1 4019 2 CC 2 CC 2 CC 2 CC 2 CC dev dev dev dev dev dev dev dev dev dev
调整后的awk脚本
awk 'BEGIN { FS=OFS="\t" } FNR == NR { # 跳过file2的表头行 if (FNR == 1) next map[$1,$2] = $5 next } { # 获取当前行对应的ref值,无匹配则为空 ref_val = (($1,$2) in map) ? map[$1,$2] : "" # 遍历所有需要检查的列(4,6,...) for (i=4; i<=NF; i+=2) { # 遍历列中的每个字符(第1、2位) for (j=1; j<=2; ++j) { # 有ref值则对比,无则直接设为dev result = (ref_val != "" && substr($i,j,1) == ref_val) ? "ref" : "dev" $0 = $0 " " result } } } 1' file2 <(gzip -dc file1.gz)
关键改动说明
- 跳过file2表头:新增
if (FNR == 1) next,避免将表头行存入匹配映射表 - 统一处理所有行:不再区分是否有匹配,对
file1的每一行都执行检查逻辑 - 无匹配行处理:无对应记录时
ref_val为空,所有对比结果直接设为dev - 支持压缩文件:用
<(gzip -dc file1.gz)直接读取解压后的file1.gz内容,无需提前解压
内容的提问来源于stack exchange,提问作者user5719890
相关产品推荐
相关产品推荐

