awk '$1=="ID" {print $0 "\tINFOextra"; next}; NF { info=$6; gsub(/.*;DP4=|;MQ=.*/, "", info); split(info, a, /,/); print $0 "\t" (a[3]+a[4])/(a[1]+a[2]+a[3]+a[4])}' inputfile.txt > outputfile.txt
# then check the content outputfile.txt and rename it if important
Como você pode ver, a solução é muito semelhante à resposta dada à sua pergunta anterior, e não mais de forma alguma. É porque o awk é extremamente ajustado para servir em problemas como o seu. Eu sugiro dar uma olhada em sua página de manual ( link ) para ver como é simples em comparação com outros (e linguagens mais gerais).
Se vários arquivos de entrada devem ser processados em vários arquivos de saída com os nomes apropriados, as opções são as seguintes:
- crie um loop no shell e inicie um processo awk para cada arquivo, um por um
-
faz o awk gravar a saída em arquivos cujos nomes são dependentes do nome do arquivo de entrada atual que a informação é armazenada na variável FILENAME do awk que é automaticamente ajustada durante o processo. Dentro do redirecionamento do código awk pode ser usado com a mesma sintaxe e resultado similar que o shell usa:
awk '$ 1 == "ID" {print $ 0 "\ tINFOextra" > FILENAME ".out"; Próximo}; NF {info = $ 6; gsub (/.*; DP4 = |; MQ =. * /, "", info); dividir (informação, a, /, /); print $ 0 "\ t" (a [3] + a [4]) / (a [1] + a [2] + a [3] + a [4]) > FILENAME ".out"} 'inputfile1.txt inputfile2.txt
Aqui, cada instância de inputfileN.txt terá um arquivo inputfileN.txt.out correspondente. FILENAME é uma string simples, portanto, qualquer tipo de manipulação dos arquivos de saída é válido.
Quando a especificação se torna complicada, de modo que o campo adicional deve aparecer em uma posição interna (não no começo ou no final), crie uma sub-rotina (chamada function in awk) para criar as linhas de saída. Essa função aqui percorre todos os campos, imprime-os como de costume, mas onde o campo adicional deve aparecer, ele escreve que depois do n-1-ésimo e antes do n-ésimo campo, tornando-se o n-ésimo. Agora, vale a pena colocar o código awk em seu próprio arquivo:
$ cat bio.awk
function myprint( str) {
for (i=1; i<=NF; ++i) {
printf "%s", $i > FILENAME ".out"
if (i==44)
printf "\t%s", str >> FILENAME ".out"
if (i!=NF)
printf "\t" >> FILENAME ".out"
}
print "" >> FILENAME ".out"
}
$1=="ID" {
myprint( "INFOextra")
next
}
NF {
info=$6
gsub(/.*;DP4=|;MQ=.*/, "", info)
split(info, a, /,/)
myprint( (a[3]+a[4])/(a[1]+a[2]+a[3]+a[4]) )
}
A chamada resulta em uma linha de comando mais curta e limpa:
awk -f bio.awk inputfile1.txt inputfile2.txt