Se o valor estiver dentro de um intervalo de impressão, a soma dos valores

1

Eu tenho dois arquivos separados por tabulações classificados.

input.txt
10      282035  282125  RNA1     -
10      4134522 4134564 RNA1     -
10      5299783 5299910 RNA2     -
10      5900317 5900359 RNA1     -

ref.txt
  1 9       137792944
  1 9       137792945
  1 10      282074
  4 10      282095
  4 10      5900329

Eu quero imprimir uma soma em valores SE certos critérios forem atendidos.

Ou seja:

IF ref $ 2 == entrada $ 1

AND

ref $ 3 cai dentro de um intervalo de min == entrada $ 2 & & max == entrada $ 3

Imprimir entrada $ 0 e soma de ref $ 1 (como entrada $ 6) mais imprimir zero (como entrada $ 6) Então o resultado deve ser assim:

10      282035  282125  RNA1     -  5
10      4134522 4134564 RNA1     -  0
10      5299783 5299910 RNA2     -  0
10      5900317 5900359 RNA1     -  4

Isso é o que eu criei:

awk '
NR == FNR {min[NR]=$2; max[NR]=$3; chr[NR]=$1; next}
 {                
     for (id in min) 
         if (($2==chr[NR])&&(min[id] < $3 && $3 < max[id])) {
             print $0, sum+=$1
             break              
         }
}                                     
' input.txt ref.txt > output.txt

Há claramente algo errado aqui, já que não recebo nenhuma saída. Além disso, ainda estou sentindo falta de "else print zero".

Alguém pode me ajudar por favor?

    
por Hele 11.09.2017 / 14:04

2 respostas

0

Isso usa o GNU awk, que permite matrizes aninhadas:

gawk '
  NR == FNR {
    ref[$2][$3] = $1
    next
  }
  $1 in ref {
    sum = 0
    for (key in ref[$1])
      if ($2 <= key && key <= $3)
        sum += ref[$1][key]
    print $0, sum
  }
' ref.txt input.txt
    
por 11.09.2017 / 16:05
0
awk 'NR==FNR {dat[NR]=$0;next} { for ( i in dat ) { split(dat[i],arr," ");tag=arr[1];min=arr[2];max=arr[3];if ($2==tag && $3 <= max && $3 >= min) { res[i]+=$1 } } } END { for (i in dat) { print dat[i]" "(res[i]!=0?res[i]:"0") } }' input ref


awk 'NR==FNR {
 dat[NR]=$0;next
} 
{ for ( i in dat ) { 
   split(dat[i],arr," ")
   tag=arr[1];
   min=arr[2];
   max=arr[3];
   if ($2==tag && $3 <= max && $3 >= min) { 
     res[i]+=$1 
     } 
   } 
} 
END { 
  for (i in dat) { 
     print dat[i]" "(res[i]!=0?res[i]:"0") 
  } 
}' input ref

Pegue cada linha de input.txt e coloque-a em um array. Então pegue cada linha de ref.txt e use a função awk dividida em dados extras no array arr. A partir desta matriz, atingimos as variáveis tag, min e max. Cada linha da matriz dat é então verificada em relação aos critérios e a matriz é incrementada de acordo. No final, o dat é colocado em loop por meio da impressão dos dados, juntamente com a contagem de res.

resultado:

10      5900317 5900359 RNA1     - 4
10      282035  282125  RNA1     - 5
10      4134522 4134564 RNA1     - 0
10      5299783 5299910 RNA2     - 0
    
por 11.09.2017 / 16:46

Tags