Extraer información del archivo

Extraer información del archivo

¿Existe una forma eficaz de analizar un archivo 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

a:

CSQ=G      ENSG00000184731         ENST00000327669    Transcript  missense_variant

El patrón es siempre |||; - luego comienza CSQy termina con el quinto campo - sin embargo ese campo no siempre es missense variantpero también puede ser algo diferente como kdjdud.

Hay muchas líneas (más de 60k) en el archivo y necesitaría extraer esta tabla de pestañas como se muestra arriba. ¿Existe una solución Python, Perl o AWK (u otra cosa) para eso?

Respuesta1

Usemos sed:

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

pythonno es rápido para manipular archivos muy grandes, esto sería mucho más rápido que python.

Ejemplo:

% 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

Respuesta2

Usando Perl:

perl -F'\|\|\|' -lane '$, = "\t"; @f = split(/;|\|/, $F[1]); shift(@f); splice(@f, 5); print(@f)' file
  • -F'\|\|\|': establece el separador de campo de entrada en |||;
  • -l: habilita el procesamiento automático de fin de línea. Tiene dos efectos separados. Primero, corta automáticamente $/ (el separador de registros de entrada) cuando se usa con -n o -p. En segundo lugar, asigna $\ (el separador de registros de salida) para que tenga el valor de octnum, de modo que a cualquier declaración impresa se le vuelva a agregar ese separador. Si se omite octnum, establece $\ en el valor actual de $/.
  • -a: activa el modo de división automática cuando se usa con -n o -p. Un comando de división implícito para la matriz @F se realiza como lo primero dentro del bucle while implícito producido por -n o -p.
  • n: hace que Perl asuma el siguiente bucle alrededor de su programa, lo que hace que itere sobre los argumentos del nombre de archivo algo así como sed -n o awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
    
  • -e: puede usarse para ingresar una línea de programa.
  • $, = "\t"; @f = split(/;|\|/, $F[1]); shift(@f); splice(@f, 5); print(@f): establece el separador de campos de salida en \t, divide el segundo campo de la línea actual en ;o |, elimina el primer campo vacío e imprime los 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
% 

Respuesta3

Esto debería funcionar para ti:

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

Ejemplo:

$ 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

Explicación

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

Respuesta4

solución pitón

#!/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]))

PRUEBA

Con la línea original de OP pegada 3 veces y ligeramente editada eninput.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

Explicación

El script abre el archivo proporcionado en la línea de comandos como argumento ( sys.argv[1]) y lee el archivo línea por línea. Primero usamos re.split()la función para dividir cada línea en múltiples delimitadores: 3 barras verticales o ;, lo que permite que los datos relevantes estén contenidos dentro de una cadena. Luego encontramos esa cadena (que contiene CSQ). Si lo encontramos, la cadena se divide nuevamente en una lista de cadenas, ahora solo usando .split()la función que usa la barra vertical como delimitador. La lista resultante se divide para tomar los primeros 5 elementos (la [0:5]parte) y se vuelve a unir en una nueva cadena usando el espacio como delimitador.

información relacionada