A primeira questão é que você não pode usar variáveis bash dentro de awk
dessa forma. $a
dentro de awk
é avaliado como campo a
, mas a
está vazio, pois não está definido em awk
, mas em bash
. Uma maneira de contornar isso é usar a opção awk
de -v
para definir a variável
-v var=val
--assign var=val
Assign the value val to the variable var, before execution of
the program begins. Such variable values are available to the
BEGIN rule of an AWK program.
Então, você poderia fazer:
while read chr a b cov; do
awk -v a="$a" -v b="$b" '($2<=a && b <= $3) {print NR}' exons.bed > out$a$b
done < reads.bed
Você tem outro erro aí. Para que uma leitura caia dentro de um exon, a posição inicial da leitura deve ser maior que a posição inicial do exon e sua posição final menor que a posição final do exon. Você está usando $2<=a && b <= $3
, que selecionará leituras cujo início está fora dos limites do exon. O que você quer é $2>=a && $3<=b
.
Em qualquer caso, executar esse tipo de coisa em um loop bash é muito ineficiente, já que ele precisa ler o arquivo de entrada uma vez para cada par de a
e b
. Por que não fazer a coisa toda em awk
?
awk 'NR==FNR{a[NR]=$2;b[NR]=$3; next} {
for (i in a){
if($2>=a[i] && $3<=b[i]){
out[i]=out[i]" "FNR
}}}
END{for (i in out){
print "Exon",i,"contains reads of line(s)"out[i],\
"of reads file"
}}' exons.bed reads.bed
O script acima produz a seguinte saída, se executada nos seus arquivos de exemplo:
Exon 1 contains reads of line(s) 1 of reads file
Exon 2 contains reads of line(s) 2 3 4 5 of reads file
Aqui está a mesma coisa em uma forma menos condensada para maior clareza
#!/usr/bin/awk -f
## While we're reading the 1st file, exons.bed
NR==FNR{
## Save the start position in array a and the end
## in array b. The keys of the arrays are the line numbers.
a[NR]=$2;
b[NR]=$3;
## Move to the next line, without continuing
## the script.
next;
}
## Once we move on to the 2nd file, reads.bed
{
## For each set of start and end positions
for (i in a){
## If the current line's 2nd field is greater than
## this start position and smaller than this end position,
## add this line number (FNR is the current file's line number)
## to the list of reads for the current value of i.
if($2>=a[i] && $3<=b[i]){
out[i]=out[i]" "FNR
}
}
}
## After both files have been processed
END{
## For each exon in the out array
for (i in out){
## Print the exon name and the redas it contains
print "Exon",i,"contains reads of line(s)"out[i],
"of reads file"
}