我有一个包含正链和负链基因的 bed 文件。我想获取正链和负链基因之间的基因间区域。有没有办法用 awk 命令做到这一点?非常感谢!
编辑:第二列和第三列是基因起始和终止位点。基本上,如果从底部开始有 + 号,我想减去第三列中的数字和前第二行中的数字。如果最后一列有 - 号,我也想从底部开始,但减去第二列中的数字和前第三行中的数字。
期望输出
chr1 820983 (860759-820983) ENSG00000269308 591 +
chr1 818542 (818542-369634) ENSG00000235249 587 +
ch1 738637 (738637-623056) ENSG00000185097 589 -
ch1 621546 (621546-140379) ENSG00000237683 586 -
输入
chr1 13885 140379 ENSG00000237683 586 -
chr1 36854 369634 ENSG00000235249 587 +
chr1 621546 623056 ENSG00000185097 589 -
chr1 738637 740137 ENSG00000269831 590 -
chr1 818542 820983 ENSG00000269308 591 +
chr1 860759 875671 ENSG00000187634 591 +
答案1
我仍然不完全理解您的解释和期望的输出(为什么有些第 1 列的值是chr1
,而有些是ch1
?为什么第一行的第 2 列是 820983 而不是 860759?),但这可能足以让您开始。
如果您不关心输出的顺序,最简单的事情似乎是反转文件中行的顺序,然后简单地滚动记录和条目的最新第 2 列值+
,并在遇到-
下一个+
或时打印/减去它们:-
$ tac file.bed | awk '
> $NF ~ /+/ {if(last2p) print $1, last2p, "(" last2p "-" $3 ")", $4, $5, $6; last2p = $2}
> $NF ~ /-/ {if(last2m) print $1, last2m, "(" last2m "-" $3 ")", $4, $5, $6; last2m = $2}
> '
chr1 860759 (860759-820983) ENSG00000269308 591 +
chr1 738637 (738637-623056) ENSG00000185097 589 -
chr1 818542 (818542-369634) ENSG00000235249 587 +
chr1 621546 (621546-140379) ENSG00000237683 586 -
如果你做关心输出顺序,那么您可以构造一对数组plus
并minus
说,然后反向迭代它们以“向上”查找下一个匹配+
或-
。这对于一行代码来说太大了,因此这里以可执行的 awk 脚本的形式呈现:
$ cat chr.awk
#!/usr/bin/gawk -f
function fooprint(a,i, j,p,q) {
split(a[i], p);
for(j=i-1;j>0;j--) {
if(j in a) {
split(a[j], q);
print q[1], p[2], "(" p[2] "-" q[3] ")", q[4], q[5], q[6];
break;
}
}
}
$NF ~ /+/ {plus[FNR] = $0}
$NF ~ /-/ {minus[FNR] = $0}
END {
for(i=NR; i>1; i--) {
if (i in plus)
fooprint(plus,i);
else if (i in minus)
fooprint(minus,i);
}
}
然后
$ ./chr.awk file.bed
chr1 860759 (860759-820983) ENSG00000269308 591 +
chr1 818542 (818542-369634) ENSG00000235249 587 +
chr1 738637 (738637-623056) ENSG00000185097 589 -
chr1 621546 (621546-140379) ENSG00000237683 586 -