Extraia informações do arquivo

Extraia informações do arquivo

Existe uma maneira eficiente de analisar um arquivo como:

2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669

para:

CSQ=G      ENSG00000184731         ENST00000327669    Transcript  missense_variant

O padrão é sempre |||; - então começa CSQe termina com o quinto campo - porém esse campo nem sempre é, missense variantmas também pode ser algo diferente como kdjdud.

Existem muitas linhas (mais de 60k) no arquivo e eu precisaria extrair esta tabela tab deli conforme mostrado acima - existe uma solução Python, Perl ou AWK (ou outra coisa) para isso?

Responder1

Vamos usar sed:

sed -r 's/.*\|\|\|;(CSQ[^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|.*/\1\t\2\t\3\t\4\t\5/' file.txt

pythonnão é rápido na manipulação de arquivos muito grandes, isso seria muito mais rápido que python.

Exemplo:

% cat file.txt 
2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669

% sed -r 's/.*\|\|\|;(CSQ[^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|.*/\1\t\2\t\3\t\4\t\5/' file.txt
CSQ=G   ENSG00000184731 ENST00000327669 Transcript  missense_variant
CSQ=G   ENSG00000184731 ENST00000327669 Transcript  missense_variant
CSQ=G   ENSG00000184731 ENST00000327669 Transcript  missense_variant
CSQ=G   ENSG00000184731 ENST00000327669 Transcript  missense_variant

Responder2

Usando Perl:

perl -F'\|\|\|' -lane '$, = "\t"; @f = split(/;|\|/, $F[1]); shift(@f); splice(@f, 5); print(@f)' file
  • -F'\|\|\|': define o separador do campo de entrada como |||;
  • -l: permite o processamento automático de finalização de linha. Tem dois efeitos separados. Primeiro, ele mastiga automaticamente $/ (o separador de registro de entrada) quando usado com -n ou -p. Segundo, ele atribui $\ (o separador de registro de saída) para ter o valor de octnum para que qualquer instrução de impressão tenha esse separador adicionado novamente. Se octnum for omitido, define $\ como o valor atual de $/.
  • -a: ativa o modo de divisão automática quando usado com -n ou -p. Um comando de divisão implícito para o array @F é feito como a primeira coisa dentro do loop while implícito produzido por -n ou -p.
  • n: faz com que o Perl assuma o seguinte loop em torno do seu programa, o que o faz iterar sobre os argumentos do nome do arquivo, como sed -n ou awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
    
  • -e: pode ser usado para inserir uma linha de programa.
  • $, = "\t"; @f = split(/;|\|/, $F[1]); shift(@f); splice(@f, 5); print(@f): define o separador do campo de saída como \t, divide o segundo campo da linha atual em ;ou |, remove o primeiro campo vazio e imprime os campos restantes.
% cat file
2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
% perl -F'\|\|\|' -lane '$, = "\t"; @f = split(/;|\|/, $F[1]); shift(@f); splice(@f, 5); print(@f)' file
CSQ=G   ENSG00000184731 ENST00000327669 Transcript  missense_variant
% 

Responder3

Isso deve funcionar para você:

cut -d"|" -f4,5,6,7,8 filename.txt | sed 's/;//g' | sed 's/|/\t/g'

Exemplo:

$ echo "2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
" | cut -d"|" -f4,5,6,7,8 | sed 's/;//g' | sed 's/|/\t/g'

CSQ=G   ENSG00000184731 ENST00000327669 Transcript  missense_variant

Explicação

cut -d"|" -f4,5,6,7,8 filename.txt   #-> split the line at | and return fields 4 to 8
| sed 's/;//g'                       #-> remove the ;
| sed 's/|/\t/g'                     #-> replace | with tab

Responder4

Solução Python

#!/usr/bin/env python
import re,sys
with open(sys.argv[1]) as fd:
    for line in fd:
        pattern=[ x for x in re.split('\|\|\||;',line)
                    if 'CSQ' in x]
        if pattern:
            print(" ".join(pattern[0].split("|")[0:5]))

TESTE

Com a linha original do OP colada 3 vezes e ligeiramente editada eminput.txt

$ ./extract_pattern.py input.txt                                                                      
CSQ=G ENSG00000184731 ENST00000327669 Transcript missense_variant
CSQ=G ENSG00000184731 ENST00000327669 Transcript random_variant
CSQ=G ENSG00000184731 ENST00000327669 Transcript other_variant

Explicação

O script abre o arquivo fornecido na linha de comando como argumento ( sys.argv[1]) e lê o arquivo linha por linha. Primeiro usamos re.split()a função para dividir cada linha em vários delimitadores - 3 barras verticais ou ;, o que permite que os dados relevantes sejam contidos em uma string. Em seguida, encontramos aquela string (que contém CSQ). Se encontrarmos, a string é dividida novamente em lista de strings, agora apenas usando .split()a função que usa barra vertical como delimitador. A lista resultante é dividida para pegar os primeiros 5 elementos (a [0:5]parte) e reunida em uma nova string usando espaço como delimitador.

informação relacionada