所以我在 awk/bash 中编写代码。我有两个文件,第一个文件的格式如下:
chr1_2376428_A_T
chr1_5465765_T_A
chr1_8958392_C_G
....
chrM_237426_C_G
该文件跨越所有染色体,并且每个染色体有多个样本。现在我的第二个文件是基因注释文件,其格式如下:
chr1 HAVANA Exon 13642 13859 ....
chr1 HAVANA START_CODON 13642 13859 ....
....
如果染色体匹配,我想搜索文件 1 中的值是否落在注释文件中起始 ($4) 和结束 ($5) 坐标所描绘的任何区域之间。
示例文本文件:
echo -e chr1_2376428_A_T"/n"chr1_5465765_T_A"/n"chr1_8958392_C_G"/n"chr1_9542312_T_G > coordinates.txt
echo -e chr1"\t"HAVANA"\t"Exon"\t"13642"\t"13859"\n"chr1"\t"HAVANA"\t"START_CODON"\t"13642"\t"13859"\n"chr1"\t"HAVANA"\t"Exon"\t"5465750"\t"5465810"\n"chr1"\t"HAVANA"\t"gene"\t"6465750"\t"6465810"\n"chr1"\t"HAVANA"\t"Exon"\t"8958350"\t"8958461"\n" | gzip -c > gencode.v34.annotation.gtf.gz
我使用了以下代码:
zcat gencode.v34.annotation.gtf.gz | awk -v File=/pathto/Coordinates.txt 'BEGIN{comm="cat "File; while(comm|getline){split($1,a,"_");dict[a[1]]=a[2];}}{if ($1 in dict){if (dict[$1]>$4 && dict[1]<$5){print $1"_"dict[$1]"_"$3}}}'
这里的问题是,我为每个染色体获得的结果是每个染色体的最后一个可能的样本,这使我认为只有键(染色体编号)的最后一个值被比较和/或只被记录。如何测试某个键的所有值?
目前成果:
None
预期结果:
chr1_5465765_Exon
chr1_8958392_Exon
谢谢你
编辑:这是上面的 awk 代码,由
gawk -o-
漂亮地打印,以便于阅读:
BEGIN {
comm = "cat " File
while (comm | getline) {
split($1, a, "_")
dict[a[1]] = a[2]
}
}
{
if ($1 in dict) {
if (dict[$1] > $4 && dict[1] < $5) {
print $1 "_" dict[$1] "_" $3
}
}
}
array[key]=value
每个键只允许一个值 - 每当设置新值时(即每个dict[a[1]] = a[2]
),它都会被覆盖dict[1]
似乎是脚本后面的一个错字最好使用生物信息学专用工具,例如 @timur-shtatland 在评论中提到的 bedtools。然而,使用 SQLite 的简单 SQL 解决方案可能是:
$ cat >sqlite-commands <<'EOD'
create table a (chr, v2, tag, start, end);
.separator \t
.import annotations_file a
create table b (chr, idx, v3, v4);
.separator _
.import samples_file b
select b.chr, b.idx, a.tag
from a join b on a.chr = b.chr
where a.start < b.idx and b.idx < a.end;
EOD
$ cat -A annotations_file
chr1^IHAVANA^IExon^I13642^I13859$
chr1^IHAVANA^ISTART_CODON^I13642^I13859$
chr1^IHAVANA^IExon^I5465750^I5465810$
chr1^IHAVANA^Igene^I6465750^I6465810$
chr1^IHAVANA^IExon^I8958350^I8958461$
$ cat samples_file
chr1_2376428_A_T
chr1_5465765_T_A
chr1_8958392_C_G
chr1_9542312_T_G
$
然后:
$ sqlite3 '' <sqlite-commands
chr1_5465765_Exon
chr1_8958392_Exon
$
我理解传递
''
因为数据库使用临时文件并允许处理不适合内存的数据。