Unix环境下如何用data.txt文件的指定列替换data.fam文件的第6列
问题分析与解决:替换fam文件指定列的awk命令错误排查
你需要把data.fam的第6列替换为data.txt中对应样本ID(第1列匹配)的第3列值,但当前的awk命令有两个关键问题,导致第6列被设为空值,最终输出缺失该列:
你的命令错误点
awk 'FNR==NR{a[$1]=$2;next}{$6=a[$3]}1' data.txt data.fam >output.fam
- 存储了错误的列:读取
data.txt时,你把第2列的值存在数组a里,但你实际需要的是data.txt的第3列值,应该改为a[$1]=$3 - 匹配了错误的键:处理
data.fam时,你用第3列($3,也就是样本的父ID,这里都是0)去匹配数组的键,而正确的匹配键应该是data.fam的第1列(样本ID),也就是$1,所以应该改为$6=a[$1]
另外,对于data.fam中存在但data.txt里没有的样本(比如20492),我们需要给它一个默认值(你预期的是0),所以可以在赋值时加上默认判断,避免空值。
正确的awk命令
awk 'FNR==NR{a[$1]=$3;next} {$6=($1 in a)?a[$1]:0}1' data.txt data.fam >output.fam
命令解释:
FNR==NR{a[$1]=$3;next}:当读取第一个文件data.txt时,用样本ID(第1列)作为键,把第3列的值存入数组a,然后跳过后续逻辑处理下一行{$6=($1 in a)?a[$1]:0}:处理第二个文件data.fam时,检查当前样本ID是否在数组a中:- 如果存在,就把第6列设为
a[$1](对应data.txt的第3列值) - 如果不存在(比如20492),就把第6列设为0(符合你的预期输出)
- 如果存在,就把第6列设为
1:等价于print $0,用于输出修改后的每一行
验证结果
用这个命令处理你提供的文件,生成的output.fam会完全符合你的预期:
20481 20481 0 0 2 1 20483 20483 0 0 1 1 20488 20488 0 0 2 1 20492 20492 0 0 1 0 20493 20493 0 0 1 0 20498 20498 0 0 2 1
内容的提问来源于stack exchange,提问作者Aryh
相关产品推荐
相关产品推荐

