Imprima conjuntos de linhas que não possuem um par correspondente

0

Estou tentando imprimir um conjunto de duas linhas que não possuem um par correspondente. Eu finalmente quero remover essas linhas.

Exemplo:

NM00123_rn5_0_1_2
XXXXXXXXXXXXXXXXXXXXXXXXXXX
NM00123_mm10_0_1_2
XXXXXXXXXXXXXXXXXXXXXXXXXXXX
NM00124_rn5_0_1_3
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
NM00124_mm10_0_1_3
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
NM00125_rn5_0_1_4
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
NM00126_rn5_0_1_5
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRr
NM00126_mm10_0_1_5
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR

A linha que começa com NM são cabeçalhos e a próxima linha é composta de seqüência de alfabetos. As linhas de cabeçalho de um par correspondem em todas as posições, exceto para rn5 e mm10. Eu quero apenas manter conjuntos de quatro linhas foram os dígitos do cabeçalho NM antes e depois de rn5 e mm10 correspondem para um par. Assim, a partir do exemplo acima: Cabeçalho na linha 1 para rn5 corresponde ao Cabeçalho na linha 3 para mm10, então mantenha isso .... mas Cabeçalho para rn5 na linha 9 não tem um par correspondente, então imprima tanto o cabeçalho quanto a próxima linha com o par. seqüência. Eu quero finalmente ter um arquivo de igual número de entradas rn5 e mm10.

Sou muito novo no uso do Unix e agradeço muito a ajuda para fazer isso. Obrigado.

Resultado esperado:

Todas as entradas acima sans a linha sem um par correspondente. Neste caso:

NM00125_rn5_0_1_4
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
    
por user210349 13.01.2017 / 22:45

2 respostas

0

Eu acho que o que você está pedindo é algo que

  • mantém um buffer de 4 linhas; e
  • se o item que segue rn5 (até a próxima nova linha) corresponder ao item seguinte mm10 (até a próxima, mas duas novas linhas) imprima e comece novamente

Provavelmente é uma maneira feia de fazer isso, mas para ilustrar com o GNU sed :

$ sed -n -e :a \
         -e '$!N; /rn5_\(.*\)\n.*\n.*mm10_\n/ {p;b}' \
         -e '/.*\n.*\n.*\n/ D' \
         -e ba infile > outfile

$ diff outfile infile
8a9,10
> NM00125_rn5_0_1_4
> zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
    
por 14.01.2017 / 02:09
0

Aqui está uma versão um pouco envolvida para o awk. Algumas diferenças da versão sed do steeldriver:

  1. Não faz suposições sobre a ordem dos registros mm10 ou rn5
  2. Ele pode lidar com um registro rn5 ausente
  3. Ele exibirá os registros não correspondentes em stderr .
  4. É muito mais código: -)

Pode ser executado com:

awk -f my_program.awk infile

O código:

# find and store a header
/^NM.*/ { header = $0; next }

# we found an mm10 line
header ~ /_rn5/ {

    # get the mm10 line that matches this rn5
    mm_match = header
    sub("_rn5", "_mm10", mm_match)

    # if we have a previous mm10, then print the pair
    if (mm_match in headers) {
        print header
        print
        print mm_match
        print headers[mm_match]

        delete headers[mm_match]
    } else {
        headers[header] = $0
    }
    next
}

# we found an mm10 line
header ~ /_mm10/ {

    # get the rn5 line that matches this mm10
    mm_match = header
    sub("_mm10", "_rn5", mm_match)

    # if we have a previous rn5, then print the pair
    if (mm_match in headers) {
        print mm_match
        print headers[mm_match]
        print header
        print

        delete headers[mm_match]
    } else {
        headers[header] = $0
    }
    next
}

Além disso, esse código pode ser adicionado ao final do arquivo para gerar quaisquer linhas sem correspondência para standard error :

# The END block is here just to output anything that was unmatched
END {
    # dump the unmatched to stderr
    for (header in headers) {
        print header > "/dev/stderr"
        print headers[header] > "/dev/stderr"
    }
}

Pode ser executado com:

awk -f my_program.awk infile > outfile 2> unmatched

Que produzirá a saída solicitada (via saída padrão) em outfile , e produzirá a entrada restante (via erro padrão) em unmatched . Para obter detalhes sobre o redirecionamento de E / S em toda a sua variedade, consulte o capítulo sobre Redirecionamentos no manual de referência do Bash.

    
por 14.01.2017 / 03:46