extrair um subconjunto de linhas de um arquivo de texto grande

4

Eu tenho um arquivo grande com 9 colunas, delimitado por tabulações. Este arquivo tem cerca de 39MB, com cerca de 250.000 linhas. A última coluna, coluna 9, tem informações como essa (observe que isso é tudo uma coluna - os espaços nelas não denotam uma nova coluna, mas são apenas os "dados" dessa coluna)

TF_binding_site_cage_181208 ZNFN1A2-91741 ;ALIAS ZNFN1A2 ;L3_ID L3_chrX_+_149850517 
TF_binding_site_cage_181208 ZNFN1A2-92447 ;ALIAS ZNFN1A2 ;L3_ID L3_chrX_-_153016326 
TF_binding_site_cage_181208 ZNFN1A2-92446 ;ALIAS ZNFN1A2 ;L3_ID L3_chrX_-_153016326 
TF_binding_site_cage_181208 ZNFN1A2-92445 ;ALIAS ZNFN1A2 ;L3_ID L3_chrX_-_153016326 
TF_binding_site_cage_181208 SNAI1-3-177789 ;ALIAS SNAI1,SNAI2,SNAI3 ;L3_ID L3_chr1_+_52294530 
TF_binding_site_cage_181208 SNAI1-3-178434 ;ALIAS SNAI1,SNAI2,SNAI3 ;L3_ID L3_chr1_-_52294717 
TF_binding_site_cage_181208 SNAI1-3-178161 ;ALIAS SNAI1,SNAI2,SNAI3 ;L3_ID L3_chr1_-_52604408 
TF_binding_site_cage_181208 SNAI1-3-177489 ;ALIAS SNAI1,SNAI2,SNAI3 ;L3_ID L3_chr1_-_52936367 
TF_binding_site_cage_181208 MEF2A,C,D-173519 ;ALIAS MEF2A,MEF2C,MEF2D ;L3_ID L3_chr8_+_144711658 
TF_binding_site_cage_181208 MEF2A,C,D-173496 ;ALIAS MEF2A,MEF2C,MEF2D ;L3_ID L3_chr8_-_145085726 
TF_binding_site_cage_181208 MEF2A,C,D-172831 ;ALIAS MEF2A,MEF2C,MEF2D ;L3_ID L3_chr8_+_145136211 
TF_binding_site_cage_181208 MEF2A,C,D-173254 ;ALIAS MEF2A,MEF2C,MEF2D ;L3_ID L3_chr9_+_696759 

Basicamente eu estou procurando as linhas que contêm apenas "MEF2 *", então no exemplo acima, ele selecionaria apenas as últimas 4 linhas. Eu também quero as linhas inteiras, não apenas esta coluna.

Eu tentei fazer isso, importando para o Excel, importando para o R, mas às vezes meu método funciona, mas eu não tenho como "checar" se eu tenho todas as minhas linhas. (As linhas com o MEF2 abrangem um par de milhares de linhas, por isso é difícil contar manualmente).

Alguém pode pensar em um algoritmo que me ajudará a extrair essas linhas sem (muito pouco) margem de erro? Eu sei que parece uma coisa básica, mas tenho medo de que minhas habilidades de regex não sejam strongs o suficiente para extrair todas as linhas.

    
por masfenix 26.11.2014 / 00:30

1 resposta

7

Isso fornecerá todas as linhas cuja 9ª coluna corresponde a MEF2 :

awk -F"\t" '$9~/MEF2/' file > output

Supondo que seu arquivo seja sempre delimitado por tabulação, isso funcionará e você poderá ficar em segurança. Essa é a margem de erro mais próxima de 0 que você conseguirá.

Se, no entanto, você tentou importar algo como R (presumivelmente usando read.table("file",sep="\t") ) e isso não funcionou, você pode ter algumas linhas com diferentes números de campos (veja no final como verificar isso). Nesse caso, supondo que você esteja sempre interessado no último campo, use $(NF) in awk para imprimir o último campo, independentemente de quantos campos houver:

awk -F"\t" '$(NF)~/MEF2/' file > output

Se ainda sentir necessidade de verificar, você pode simplesmente extrair todas as linhas que correspondem a MEF2 , independentemente de onde a correspondência é, e comparar os resultados:

grep MEF2 file > output2

Depois de ter isso, você pode usar wc para verificar se eles têm o mesmo número de linhas. Se não, descubra onde eles diferem executando

grep -vFf output output2

Esse comando irá imprimir quaisquer linhas na saída2 que não estejam presentes na saída1. Se houver algum, provavelmente eles terão MEF2 em algum lugar da linha, mas não no nono campo. Se estiver no 9º campo, você sabe que seu arquivo não está separado por tabulações e há algo errado com seus dados.

O awk acima é provavelmente a solução mais simples, mas aqui estão alguns outros que fazem a mesma coisa:

  • Perl

    perl -F"\t" -lane '$F[8]=~/MEF2/ && print' file
    
  • sed (este pode coincidir com linhas erradas se você tiver mais de 9 campos)

    sed -n '/\t.*\t.*\t.*\t.*\t.*\t.*\t.*\t.*MEF2.*/p' file
    
  • grep

    grep -P '^.+?\t.*\t.*\t.*\t.*\t.*\t.*\t.*\t.*MEF2.*' file
    

Se tudo isso não produzir a mesma saída, você sabe que há um problema no seu arquivo. Só mais uma coisa que você pode verificar é certificar-se de que todas as suas linhas tenham 9 campos. Se não, você sabe que há um problema:

awk -F"\t" 'NF!=9' file

O texto acima imprimirá todas as linhas que não tenham exatamente 9 campos separados por tabulações. Se houver saída, as linhas impressas serão problemáticas.

    
por 26.11.2014 / 00:56