Remova x linhas antes e y linhas depois da linha n (que corresponde a um padrão) em um arquivo

1

Estou tentando remover um bloco de quatro linhas de um arquivo de texto se a segunda linha corresponder ao N + do Regex. O arquivo de texto é composto de vários formatos repetidos de 4 linhas, por exemplo:

@HEADER1
ACTGCNNNT
+
583@#!NMY
@HEADER2
ANNTGCGGG
+
4123N@!&*

A primeira linha do padrão de quatro blocos sempre começará com @, no entanto, @ também pode aparecer em qualquer lugar na quarta linha e, como o padrão que estou procurando, N + também pode aparecer na quarta linha, simplesmente grep para N +.

Qualquer ideia seria muito apreciada:)

    
por Lynne Smith 16.07.2015 / 17:58

2 respostas

2

sed -ne:n -e's/\n/&/3;tp'  \
          -e'$!{N;bn' -e\} \
     -e:p -e'/\n.*N.*\n/p' \
<in >out

Se a sua entrada ocorrer em blocos regulares de quatro linhas por, e se você estiver procurando pelo menos um N que não ocorra no último desses quatro, o bit acima de sed deve atender às suas necessidades. Ele supõe que todo o seu arquivo de entrada será bloqueado em grupos de quatro linhas. Se este não for o caso, deixe-me saber e posso torná-lo um pouco menos presunçoso.

De qualquer forma, primeiro sed reúne 4 linhas de entrada - ou puxa linhas de entrada até que 3 \n ewline delimitadores sejam encontrados no espaço padrão - e em seguida ele procura por um N não ocorre na primeira ou na última das quatro linhas que acabamos de reunir. Se for encontrado, p reimpressa o grupo de quatro linhas, senão nada será impresso e o próximo ciclo começará com o próximo grupo de 4 linhas.

Mas, aparentemente, você está tentando remover o bloco em questão. Nesse caso:

sed -e'$!N;/\n.*N/{$!N;$!N;d' -e'};n;n' <in >out

... fará o truque. Primeiro, ele anexa a linha de entrada N ext ao espaço padrão e, em seguida, procura por um N que ocorre na segunda linha de um bloco de 4 linhas e, se for encontrado, sed puxa mais duas linhas em qualquer linha que seja ! e não $ antes de d eletrar o bloco inteiro. Se a segunda linha não coincidir com N , ela substitui o espaço padrão duas vezes pela linha de entrada n ext - impressão automática como ocorre - e imprime automaticamente último destes também.

Você também pode usar o primeiro bit de sed e apenas /\n.*N.*\n/!p em vez de p para o último endereço também, é claro. Isso pode ser vantajoso na medida em que você pode alterá-lo mais facilmente trocando o 3 para qualquer outro número de linhas por bloco que possa lhe interessar.

    
por 16.07.2015 / 19:28
-1

Perl para o resgate!

Salvar como remove-blocks.pl , executado como perl remove-blocks.pl input_file > output_file .

#!/usr/bin/perl
use strict;
use warnings;

my @four_lines;                      # Buffer to hold a block.
while (<>) {                         # Read the input line by line.
    if (@four_lines < 3) {           # Not reading the last line?
        push @four_lines, $_;        # Save it to the buffer.

    } else {
        print @four_lines, $_ if $four_lines[1] !~ /N+/;
        undef @four_lines;           # Clear the buffer.
    }
}
    
por 16.07.2015 / 18:08