파일에서 라인 n 앞의 x 라인과 라인 뒤의 y 라인 삭제(일치하는 패턴)

파일에서 라인 n 앞의 x 라인과 라인 뒤의 y 라인 삭제(일치하는 패턴)

두 번째 줄이 정규식 N+와 일치하면 텍스트 파일에서 네 줄의 블록을 제거하려고 합니다. 텍스트 파일은 다음과 같이 반복되는 4줄 형식으로 구성됩니다.

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

4블록 패턴의 첫 번째 줄은 항상 @로 시작하지만 @는 네 번째 줄 어디든 나타날 수 있고, 제가 찾고 있는 패턴 때문에 N+도 네 번째 줄에 나타날 수 있는데, N+를 grep하면 됩니다.

어떤 아이디어라도 크게 감사하겠습니다 :)

답변1

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

입력 내용이 4줄마다 일반 블록으로 나타나고 최소한 하나의 줄을 찾고 있는 경우N저것아니요이 네 가지 중 마지막에 발생하면 위의 사항이 sed귀하의 필요에 적합해야 합니다. 전체 입력 파일이 네 줄의 그룹으로 분할된다고 가정합니다. 그렇지 않은 경우 알려주시면 의견을 덜 수 있도록 하겠습니다.

어쨌든, 먼저 sed4개의 입력 라인을 수집하거나 \n패턴 공간에서 3개의 라인 구분 기호를 찾을 때까지 입력 라인을 끌어온 다음 찾습니다.N방금 수집한 4개 행 중 첫 번째 또는 마지막 행에서는 이러한 현상이 발생하지 않습니다. 발견되면 p4줄 그룹을 인쇄하고, 그렇지 않으면 아무것도 인쇄하지 않으며 다음 주기는 다음 4줄 그룹으로 시작됩니다.

하지만 분명히, 당신은 노력하고 있어요제거하다문제의 블록. 이 경우:

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

...작동할 겁니다. 먼저 N외부 입력 라인을 패턴 공간에 추가한 다음 패턴 공간이 있는지 확인합니다.N4줄 블록의 두 번째 줄에서 발생하며, 발견되면 전체 블록을 삭제하기 전에 마지막 줄이 아닌 sed줄에 두 줄을 더 끌어옵니다 . 두 번째 줄의 경우!$d아니요성냥N, 외부 입력 라인(autoprint)으로 패턴 공간을 두 번 덮어쓰고 n자동으로 마지막 라인을 인쇄합니다.

물론 마지막 주소 대신에 의 sed첫 번째 숫자를 사용해도 됩니다. 이는 관심 있는 다른 행 수로 전환하여 블록당 행 수를 더 쉽게 변경할 수 있기 때문에 유리할 수 있습니다 ./\n.*N.*\n/!pp3

답변2

Perl이 구출하러 옵니다!

로 저장 remove-blocks.pl하고 로 실행합니다 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.
    }
}

관련 정보