我正在处理一个非常大的数据集,格式如下:
chr1 45162 . . C T
chr1 45162 . . C T
chr1 45162 A . . T
chr1 45162 . . C T
chr1 45257 A . . T
chr1 45257 A . . T
chr1 45413 A . . T
chr1 46844 A . C .
chr1 72434 A G . .
chr1 72434 A G . .
chr1 72434 A G . .
chr1 72434 A G . .
chr1 72515 A . C .
chr1 72515 A . . T
chr1 77689 A G . .
我想要的输出是这样的:
chr1 45162 A . C T
chr1 45257 A . . T
chr1 45413 A . . T
chr1 46844 A . C .
chr1 72434 A G . .
chr1 72515 A . C T
chr1 77689 A G . .
本质上,对于第 2 列中的每个唯一值,我需要查看它具有的所有属性,这些属性可能存储在单独的行中。
所以,如果我有:
chr1 100 A . C .
chr1 100 . G . T
我希望输出中的行是:
chr1 100 A G C T
我有一个脚本,我相信它可以正常工作,但它太慢了。我认为必须有一种更简单的方法可以通过简单的awk
脚本来完成此操作。
我当前的版本在这里:http://ideone.com/e.js/ETBRz3
但是,就像我说的,我认为应该有一个几乎 1 衬垫版本可能仅使用awk
.
欢迎所有建议。
(如果它可以简化事情,我可以返回并修改生成此文件的脚本,使空字段是空字符串而不是“.”字符。)
答案1
这是一种方法:
$ awk '$2!=old && NR>1 {for (i=1;i<=NF;i++) printf a[old","i]" "; print"";} {old=$2;for (i=1;i<=NF;i++) {if (a[$2","i]=="." || a[$2","i]=="") a[$2","i]= $i}} END{for (i=1;i<=NF;i++) printf a[old","i]" "; print"";}' file
chr1 45162 A . C T
chr1 45257 A . . T
chr1 45413 A . . T
chr1 46844 A . C .
chr1 72434 A G . .
chr1 72515 A . C T
chr1 77689 A G . .
怎么运行的
$2!=old && NR>1 {for (i=1;i<=NF;i++) printf a[old","i]" "; print"";}
在第一行之后,每当我们遇到第二列的新值时,就打印出前一个值的结果。
old=$2;for (i=1;i<=NF;i++) {if (a[$2","i]=="." || a[$2","i]=="") a[$2","i]= $i}
a
使用当前行的值更新数组。GNU
awk
有很好的二维数组。然而,为了兼容性,我使用 POSIX 兼容的替代品。END{for (i=1;i<=NF;i++) printf a[old","i]" "; print"";}
最后一行之后,打印出最后部分的信息。
答案2
未排序行的另一种变体:
awk '{
k[$2]=$1;
for(i=3;i<7;i++){
if(l[$2,i]=="." || l[$2,i]=="")
l[$2,i]=$i;
}
}
END{
for(n in k){
printf("%s %s ",k[n],n);
for(m=3;m<7;m++)
printf("%s ", l[n,m]);
print "";
}
}' file
简短的解释:
通过文件脚本创建两个关联数组:k
with field#2
as index 和l
with index field#2,Next_fields_number
。当文件中的所有行都通过时,脚本启动两个循环来打印第一个数组和第二个数组中的字段。
答案3
一个perl
办法:
$ perl -anle '
for (2..$#F) {
$h{join(" ",@F[0..1])}->{$_} ||= $F[$_];
$h{join(" ",@F[0..1])}->{$_} = $F[$_] if $F[$_] ne ".";
}
END { print "$_ @{$h{$_}}{sort keys %{$h{$_}}}" for sort keys %h }
' file
chr1 45162 A . C T
chr1 45257 A . . T
chr1 45413 A . . T
chr1 46844 A . C .
chr1 72434 A G . .
chr1 72515 A . C T
chr1 77689 A G . .