Obtém as linhas apenas com campos específicos

0
#CHROM  POS     T1      T10     T11     T12     T13     T2      T3      T4      T5      T6      T106    T107    T108    T109    T110    T112    T114    T116    T120    T122    T125    T128    T129    T130
Aradu.A01       300806  H       B       B       B       B       B       B       B       H       B       B       H       B       B       B       B       B       B       B       B       B       B       B
Aradu.A01       386907  A       A       A       A       A       A       A       A       A       A       A       A       H       A       A       A       A       A       H       A       A       A       A
Aradu.A01       463100  B       B       A       A       A       A       A       H       B       A       A       H       H       H       H       H       B       A       B       A       H       H       A
Aradu.A01       471639  A       A       A       A       H       A       A       H       A       A       H       A       A       A       A       A       H       A       A       A       H       A       A
Aradu.A01       644024  H       B       B       B       B       B       B       B       H       H       B       H       H       B       B       B       H       B       H       B       B       B       H
Aradu.A01       756331  H       H       H       H       H       H       H       H       B       B       B       H       H       H       H       H       B       H       H       H       B       B       B
Aradu.A01       768081  A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A
Aradu.A01       783066  A       A       H       A       H       H       A       A       A       A       H       A       H       A       A       A       A       A       A       H       A       A       H
Aradu.A01       812865  H       B       H       H       H       H       H       H       H       H       H       H       H       H       H       H       B       B       H       H       B       B       H
Aradu.A01       976731  A       H       A       H       H       A       H       H       A       H       H       A       H       H       A       A       H       A       H       A       A       A       H
Aradu.A01       1089311 A       H       H       H       H       A       A       A       H       A       H       B       A       H       H       H       H       H       A       A       H       H       H
Aradu.A01       1089991 A       A       A       H       A       A       H       A       A       H       A       A       A       A       H       A       A       A       A       A       A       A       H
Aradu.A01       1113781 H       H       H       H       H       H       H       A       H       H       H       H       H       H       A       H       H       A       H       A       H       H       H
Aradu.A01       1160441 B       B       B       B       B       B       H       B       H       B       B       B       B       B       H       B       B       B       B       B       B       B       B
Aradu.A01       1638873 B       H       B       B       H       B       B       B       B       B       B       B       H       H       H       B       B       B       B       B       H       B       B
Aradu.A01       1638907 B       H       B       B       H       B       B       B       H       B       B       B       H       H       H       B       B       B       B       B       H       B       B

Alguém pode me ajudar com um código awk que só pode me obter as linhas que têm campos com "A" e "B" nele? As linhas com o
1) apenas "A" e "H",
2) somente "B" e "H" NÃO devem ser considerados.

Cada um deve ter A e B. Se H também estiver presente com A e B, a linha também deve ser considerada. Em resumo, é necessário ter apenas as linhas com "A" e "B" e se "H" estiver lá junto com "A" e "B", essa linha também deve ser considerada:

NR>1  {for(i=3;i<=NF;i++)
        { if ( $i ~ "A" && $i ~ "B" && $1 ~ "H" ) ;
       } ## if ;
       ## for loop is done
       print ;

O código acima retorna o arquivo de saída como o arquivo de entrada.        }

    
por gaurav agarwal 06.01.2017 / 17:31

2 respostas

2

Seu script tem vários problemas:

  • Ele testa se algum campo corresponde a "A" e
  • Está procurando H , quando não importa se H aparece ou não
  • Ele está procurando por H em $1 (o primeiro campo), sempre que o ciclo é
  • O resultado de todos esses testes não faz diferença: o teste if não tem ação correspondente. O print é sempre alcançado para cada linha.

Para rastrear se A e B estão presentes na mesma linha (em campos diferentes), você poderia usar uma variável para cada:

NR>1  {
    #beginning of line - no As or Bs seen yet
    A=0
    B=0
    #looping over all fields except the first two
    #break as soon as both A and B found
    for(i=3; A*B == 0 && i<=NF; i++) {
        if ( $i ~ "A" ) A=1
        if ( $i ~ "B" ) B=1
   }
    #print line if A and B were found
    if (A && B) print
}
    
por 06.01.2017 / 18:07
0

Não é uma solução awk , mas esse grep parece resolver o problema:

egrep '^Aradu\.[A-Z][0-9]{2}.*A.*B|^Aradu\.[A-Z][0-9]{2}.*B.*A' aradu
Aradu.A01       463100  B       B       A       A       A       A       A       H       B       A       A       H       H       H       H       H       B       A       B       A       H       H       A
Aradu.A01       1089311 A       H       H       H       H       A       A       A       H       A       H       B       A       H       H       H       H       H       A       A       H       H       H

Onde aradu é o seu arquivo de exemplo.

Editar, Divisão de regex:
^Aradu\.[A-Z][0-9]{2} = Linhas que começam com 'Aradu' seguidas por um literal '.' seguido por qualquer caractere maiúsculo, seguido por qualquer inteiro duas vezes.
.*A.*B = Seguido por qualquer caractere, qualquer número de vezes ( .* ), seguido por literal 'A', seguido por literal 'B'
| = Lógico ou.
(O mesmo começo da expressão até)
.*B.*A = Qualquer caractere, repetido qualquer número de vezes, seguido por um literal 'B', seguido por um literal 'A'.

grep não tem um operador && (lógico e), é o mais próximo (que eu saiba) você pode procurar uma linha com A && B || B && A .

    
por 06.01.2017 / 17:53