시작 그룹 패턴을 따르는 sed 추출 라인

시작 그룹 패턴을 따르는 sed 추출 라인

현재 해결하는 데 도움이 필요한 문제가 발생했습니다. 올바른 방향을 가리키는 것조차 도움이 됩니다.

줄이 많은 파일이 있는데 특정 패턴을 따르는 특정 줄 "그룹"만 추출하고 싶습니다. (한 줄은 로 시작해야 하고 A, 다음 줄은 로 시작해야 하며 B, 다음 줄은 로 시작해야 합니다 C)

예: 모드: , A, B순서 C로 시작합니다 .

입력하다:

A1
B1
C1
D1
A2
B2
D2
A3
D3
A4
B4
C4
A5
B5
D5

산출:

A1
B1
C1
A4
B4
C4

답변1

또 다른 해결책 awk:

awk 'p2~/^A/ && p1~/^B/ && /^C/{print p2 RS p1 RS $0} {p2=p1; p1=$0}'

perl전체 입력을 단일 문자열로 읽습니다 .

perl -0777 -ne 'print /^A.*\nB.*\nC.*\n/mg'

그리고립그렙편리한 다중 라인 매칭 옵션을 지원합니다.-U

rg -oUN '^A.*\nB.*\nC.*'

여기서 -o옵션은 일치하는 부분만 가져오는 것이고 -N옵션은 출력에서 ​​줄 번호를 방지하는 것입니다.

답변2

Sed 솔루션도 원한다면 보기 흉하지만 작동할 것입니다.

sed -n '
  /^A/{
    N
    /\nB/!D
    N
    /\nC/!{
      s/\n//
      D
    }
    p
  }
' file

-npsed에게 명령에 도달하지 않는 한 아무것도 인쇄하지 말라고 지시합니다 .

첫 번째 부분을 이해하면 나머지 부분도 이해할 수 있습니다.

  • /^A/패턴 공간이 A로 시작하면,
    • N패턴 공간에 다음 줄을 추가합니다.
    • /\nB/!D패턴 공간에 B 뒤에 개행 문자가 없으면 첫 번째 개행 문자 앞의 모든 내용이 삭제되고 입력을 읽지 않고 결과 패턴 공간으로 다시 시작됩니다.

짧막 한 농담:sed -n '/^A/{N;/\nB/!D;N;/\nC/!{s/\n//;D};p}' file

답변3

다음 awk절차가 작동합니다.

awk 's==2{if (/^C/) {s=0; p=p ORS $0; print p} else {s=0}}\
     s==1{if (/^B/) {s=2; p=p ORS $0} else {s=0}}\
     s==0{if (/^A/) {s=1; p=$0}}' input.txt 

이는 내부 "상태" 플래그를 유지하여 s시퀀스의 어떤 지점(0: 시작을 찾을 수 없음, 1: A찾을 수 없음, 2: 시퀀스 A에서 발견 B)을 확인하고 텍스트를 버퍼에 축적합니다 p.

  • A과 가 발견 B되고 현재 줄이 로 시작하면 C현재 줄을 버퍼에 추가하고 인쇄합니다. 상태 재설정0
  • 발견 되고 A현재 줄이 로 시작하면 B현재 줄을 버퍼에 추가하고 상태를 2(= AB발견) 으로 설정합니다.
  • 시작 부분을 아직 찾지 못했고 현재 줄이 로 시작하는 경우 A이를 버퍼에 추가하고 상태를 로 설정합니다 1.

답변4

이전 상태가 A->B->C로 이어지는 경우에만 sed에서 상태 머신을 설정하여 다음 상태로 진행할 수 있습니다.

그렇지 않으면 머리를 자르고 다시 시작하십시오.

$ sed -e '$d;/\n/d
    /^A/N;/\nB/!D
    $!N;/\nC/!D
' file
A1
B1
C1
A4
B4
C4

다음 grep 코드는 PCRE 옵션으로 gnu grep을 컴파일한 경우 또 다른 방법입니다.

$ grep -zoP '(?m)^A.*\nB.*\nC.*\n' file | tr -d '\0'

관련 정보