Imprima um grupo de linhas se elas contiverem strings específicas

4

Eu tenho um arquivo ( file 1 ) que parece com isso:

>C 0
0   4231aa, >A6_03412... at 1:4226:1:4240/95.44%
1   4240aa, >A5_01600... *
>C 1
0   4159aa, >FG1_03697... *
>C 2
0   3942aa, >A3_03045... at 1:3942:1:3945/96.50%
1   3945aa, >A4_03199... *
2   3942aa, >A7_02989... at 1:3942:1:3945/92.11%
3   3941aa, >A6_03202... at 1:1:1:1/96.35%

Eu considero a parte entre os dois >C como subgrupo. Então, por exemplo, este é um subgrupo

 >C 0
 0  4231aa, >A6_03412... at 1:4226:1:4240/95.44%
 1  4240aa, >A5_01600... *

Eu tenho outro arquivo ( file 2 ) contendo strings dentro do subgrupo:

A6_03412
A4_03199
.....

Eu quero imprimir todos os subgrupos que contêm a string em file 2 . Então, considerando que em file 2 eu só tenho as strings acima mencionadas, a saída deve ser:

>C 0
0   4231aa, >A6_03412... at 1:4226:1:4240/95.44%
1   4240aa, >A5_01600... *
>C 2
0   3942aa, >A3_03045... at 1:3942:1:3945/96.50%
1   3945aa, >A4_03199... *
2   3942aa, >A7_02989... at 1:3942:1:3945/92.11%
3   3941aa, >A6_03202... at 1:1:1:1/96.35%

Isso é difícil, alguma sugestão de como fazer isso com um script bash?

    
por efrem 09.03.2015 / 19:36

2 respostas

4

Uma solução de duas partes usando Perl e grep:

perl -pe 's/^>C \d+$/
awk -v RS='>C ' '{printf "
perl -pe 's/^>C \d+$/
awk -v RS='>C ' '{printf "%pre%>C %s", $0}' foo | grep -zFf ba
$&/' file1 | grep -zFf file2
>C %s", $0}' foo | grep -zFf ba
$&/' file1 | grep -zFf file2
  • Como >C <some number> separa os grupos, eu correspondi e insiro um caractere nulo ASCII ( grep ) à frente de cada grupo.
  • Então, posso aproveitar a capacidade de -z de lidar com linhas delimitadas por NUL ( -f file2 ), durante a leitura de padrões de um arquivo ( >C ).

Com o awk, eu faria algo semelhante, usando %code% como separador de registro e imprimindo um NUL antes de cada registro:

%pre%     
por muru 09.03.2015 / 19:50
0

Aqui está uma abordagem em Python:

#!/usr/bin/env python2
with open('file_1') as f_1, open('file_2') as f_2:
    f_1_subgroups = f_1.read().split('>C')
    f_2_lines = [line.rstrip() for line in f_2]
    for subgroup in f_1_subgroups:
        for line in f_2_lines:
            if line in subgroup:
                print '>C' + subgroup

Aqui primeiro dividimos o "arquivo_1" em subgrupos usando o delimitador >C , depois procuramos as linhas de "arquivo_2" no subgrupo. Se encontrado, imprimimos o subgrupo.

Uso da compreensão da lista:

#!/usr/bin/env python2
with open('file_1') as f_1, open('file_2') as f_2:
    f_1_subgroups = f_1.read().split('>C')
    f_2_lines = [line.rstrip() for line in f_2]
    print ''.join(['>C' + subgroup for line in f_2_lines for subgroup in f_1_subgroups if line in subgroup])
    
por heemayl 09.03.2015 / 19:55