我有一个包含五列的表格。如果它们重叠,我想合并起始和结束列,并且具有相同的RNAiclone和target_mRNA名称。如果两个条目的起始端是:(A)1-10,11-20表示重叠范围;而(B)1-10,12-20表示无重叠范围。 RNAilength(nt)对于类似的RNAiclone是相同的。
input.txt中
RNAiclone RNAilength(nt) target_mRNA start end
siRNA1 10 mRNA1 1 10
siRNA1 10 mRNA1 11 20
siRNA1 10 mRNA1 17 30
siRNA1 10 mRNA2 18 19
siRNA2 20 mRNA2 1 10
siRNA2 20 mRNA2 9 100
预期output.txt
RNAiclone RNAilength(nt) target_mRNA start end
siRNA1 10 mRNA1 1 30
siRNA1 10 mRNA2 18 19
siRNA2 20 mRNA2 1 100
program.awk
BEGIN{
i=0;
s="";
m="";
OFS="\t";
}
{
if (s!=$1 && m!=$3){
if (s != "" && m!= ""){
combine(chr,s,m,i);
}
i=0;
s="";
}
s=$1;
m=$3;
chr[i,0]=$4;
chr[i,1]=$5;
i++
}
END{
combine(chr,s,m,i);
}
function combine(arr,s,m,i) {
j=0;
new[j,0]=arr[0,0];
new[j,1]=arr[0,1];
for (k=1;k<i;k++)
{
if ((arr[k,0]<=new[j,1])&&(arr[k,1]>=new[j,1])){
new[j,1]=arr[k,1];
}
else if (arr[k,0]>new[j,1]){
j++;
new[j,0]=arr[k,0];
new[j,1]=arr[k,1];
}
}
for (n=0;n<=j;n++){
print s,m,new[n,0],new[n,1]
}
}
我正在使用命令&#34; wk -f program.awk input.txt&gt;运行脚本。 output.txt&#34;,但我没有得到预期的结果。你能帮我纠正一下这个剧本吗?非常感谢你。
答案 0 :(得分:0)
尝试重启比调试代码更容易。这是awk的替代品。将以下内容放入可执行的awk文件中:
#!/usr/bin/awk -f
BEGIN { OFS="\t" }
/^RNA/ { print; next }
{
key = $1 OFS $2 OFS $3
# new key or new range, print last line
if( key != l_key || l_end+1 < $4 ) {
if( FNR>1 && l_key ) { print l_key, s[l_key], l_end }
s[key]=$4
}
l_key=key
l_end=$5
}
END { print l_key, s[l_key], l_end } # print final range
调用该文件awko
(和chmod +x awko
),然后像awko input.txt
一样运行,提供以下内容:
RNAiclone RNAilength(nt) target_mRNA start end
siRNA1 10 mRNA1 1 30
siRNA1 10 mRNA2 18 19
siRNA2 20 mRNA2 1 100
可以与awko input.txt | column -t
重新对齐:
RNAiclone RNAilength(nt) target_mRNA start end
siRNA1 10 mRNA1 1 30
siRNA1 10 mRNA2 18 19
siRNA2 20 mRNA2 1 100
所以最后的命令是
awko data | column -t > output.txt
这至少有以下假设:
input.txt
答案 1 :(得分:0)
您已经收到了awk
个答案,但这里的版本在perl
中也是如此:
use strict;
use warnings;
my $last;
while (<>) {
my @cols = split;
my $key = join ' ', splice @cols, 0, 3;
my ($start, $end) = @cols;
if ($last) {
if ($last->[0] ne $key || $last->[2] < $start - 1) {
print "@$last\n"
} else {
$start = $last->[1];
$end = $last->[2] if $end < $last->[2];
}
}
$last = [$key, $start, $end];
}
print "@$last\n";
执行此程序perl merge_range.pl file.dat
会得到以下结果:
RNAiclone RNAilength(nt) target_mRNA start end
siRNA1 10 mRNA1 1 30
siRNA1 10 mRNA2 18 19
siRNA2 20 mRNA2 1 100
假设数据的排序方式与示例数据类似。要格式化列,只需通过column -t
。