두 번째 패턴에 고유한 두 패턴 사이의 모든 선을 찾으시겠습니까?

두 번째 패턴에 고유한 두 패턴 사이의 모든 선을 찾으시겠습니까?

아래에 나열된 파일이 있다고 생각해 보세요. 정규식 패턴의 각 인스턴스에서 모든 Word A행을 선택해야 합니다.앞으로정규식 패턴 Word D.

Word A
Word B
Word C
Word D
Word E
Word F
Word G
Word A
Word H
Word I
Word D
Word J
Word A
Word K
Word D
Word L
Word M
Word A
Word D

A와 사이의 줄 수는 다양합니다 D. 때로는 D다음 줄입니다. 이것은 내가 필요한 출력입니다.

Word A
Word B
Word C
Word A
Word H
Word I
Word A
Word K
Word A

이는 awk, Perl, Python 또는 sed를 사용하여 수행할 수 있습니다. 파일이 있는 RHEL6 서버에 설치되어 있으면 문제가 되지 않습니다.

답변1

AWK 사용:

awk '/Word A/ { m = 1 } /Word D/ { m = 0 } m'

답변2

여기에 awk해결책이 있습니다

awk \
  -vstart='Word A' \
  -vend='Word D' \
  '{
     if ($0==end  ) {flag=0;next};
     if ($0==start) {flag=1};
     if (flag==1) {print $0};
  }'

정규식 처리에는 약간의 변경만 필요합니다.

awk \
  -vstart='Word[ ]A' \
  -vend='Word[ ]D' \
  '{
     if ($0 ~ end  ) {flag=0;next};
     if ($0 ~ start) {flag=1};
     if (flag==1) {print $0};
  }'

답변3

사용행복하다(이전 Perl_6)

~$ raku -ne '.put if / Word \h A / fff^ / Word \h D /;'  file

Raku는 Perl 계열의 프로그래밍 언어입니다. 강력한 정규식 엔진을 갖춘 "연산자가 풍부한" 언어입니다. 위에서는 Raku의 sed와 유사한 "트리거" 연산자 -ne와 함께 자동 인쇄되지 않는 한 줄씩 플래그가 사용되었습니다 .fff

Raku에는 , 심지어 를 fff포함하여 sed와 유사한 중위 연산자의 다양한 "특성"이 포함되어 있습니다 . 각 정규 표현식이 인식되면 캐럿은 인식된 줄을 출력에서 ​​제거해야 함을 나타냅니다.fff^^fff^fff^^

입력 예:

Word A
Word B
Word C
Word D
Word E
Word F
Word G
Word A
Word H
Word I
Word D
Word J
Word A
Word K
Word D
Word L
Word M
Word A
Word D

예제 출력:

Word A
Word B
Word C
Word A
Word H
Word I
Word A
Word K
Word A

위의 코드는 OP의 테스트 사례를 해결합니다. 하지만 Regexes가 실제로 같은 줄에 있으면 어떻게 될까요 /start/? /stop/이 문제의 경우 Raku의 awk 유사 ff연산자를 사용해 볼 수 있습니다.

~$ echo 'AB\nCD\nEF' | raku -ne 'say $_ if /A/ ff /B/;'
AB
~$ echo 'AB\nCD\nEF' | raku -ne 'say $_ if /A/ ff /C/;'
AB
CD

Raku의 sed 유사 fff연산자와 비교해 보세요.

~$ echo 'AB\nCD\nEF' | raku -ne 'say $_ if /A/ fff /B/;'
AB
CD
EF
~$ echo 'AB\nCD\nEF' | raku -ne 'say $_ if /A/ fff /C/;'
AB
CD

https://docs.raku.org/routine/fff
https://docs.raku.org/routine/ff
https://raku.org

답변4

TXR 리스프awk매크로는 이것을 직접 지원합니다.rng (범위) 연산자에는 다양한 방법으로 범위의 시작이나 끝에서 레코드를 제외하는 9가지 변형이 있습니다.

$ txr -e '(awk ((rng- #/Word A/ #/Word D/)))' data
Word A
Word B
Word C
Word A
Word H
Word I
Word A
Word K
Word A

또한 Awk의 범위 연산자와 달리 다른 연산자와 함께 사용됩니다. 예를 들어, footo bar범위에 있는 레코드를 인쇄하려고 한다고 가정합니다 .그리고start범위 내 에서는 end데이터에서 범위가 어떻게 겹치는지에 관계없이 다음을 수행합니다.

(awk ((and (rng #/foo/ #/bar/)
           (rng #/start/ #/end/))))

관련 정보