패턴을 검색하고 다른 패턴으로 시작하는 처음 몇 줄을 인쇄합니다.

패턴을 검색하고 다른 패턴으로 시작하는 처음 몇 줄을 인쇄합니다.

패턴을 찾으려면 grep을 수행해야 하고, 패턴을 찾으면 해당 패턴 이전에 다른 패턴을 찾아서 그 사이에 있는 모든 줄을 인쇄해야 합니다.

더 나은 예:

1 a
2 a
3 a
4 a
5 a
6 b
7 c
8 d
9 xyz
10 xyz
11 a
12 a

grep을 누른 xyz다음 첫 번째 a줄 을 grep xyz하고 모든 줄을 인쇄합니다.

출력(첫 번째로 나타나는 출력 , 파일의 다른 출력은 a신경 쓰지 않음 ):a

5 a 
6 b
7 c
8 d
9  xyz
10 xyz

답변1

Perl의 솔루션은 다음과 같습니다.

perl -nlE '
    if    (/a/)   { @buffer = ($_) }
    elsif (/xyz/) { push @buffer,$_; say for @buffer }
    else          { push @buffer,$_}
' your_file

어떻게 작동하나요?

파일을 한 줄씩 읽고 다음 세 가지 작업 중 하나를 수행합니다.

  1. 현재 행이 패턴과 일치하면 a현재 행이 배열에 할당됩니다 @buffer.
  2. 현재 줄이 패턴과 일치하면 xyz현재 줄을 버퍼에 푸시하고 버퍼의 내용을 인쇄합니다.
  3. @buffer위의 어느 것도 해당되지 않으면 현재 행을 배열 에 추가합니다 .

따라서 새 줄이 패턴과 일치할 때마다 a의 내용이 @buffer삭제되고 현재 줄로만 대체됩니다. 이렇게 하면 가장 a앞쪽에 있는 것을 찾을 수 있습니다 xyz.

물론 내가 사용한 정규식을 귀하의 사례와 관련된 실제 정규식으로 바꿔야 합니다.

답변2

생각하다당신은 다음과 같은 것을 할 수 있습니다

grep -zPo '.*a(?s)(?(?!a).)*?xyz' file

(귀하의 버전이 PCRE 확장을 지원할 만큼 충분히 새로운 경우 GNU grep을 사용하십시오) 또는

pcregrep -Mo '.*a(?s)(?(?!a).)*?xyz' file

xyz출력에서 두 번째 인스턴스를 일치시키려면 ?마지막 예를 들어 grep -zPo '.*a(?s)(?(?!a).)*xyz' file.


아마도 더 나은 테스트는 주어진 시작 및 중지 조건 모두에 대해 다중 문자 모드를 사용하는 것입니다.

$ cat file
1 abc    
2 abc
3 abc
4 abc
5 abc
6 bbc
7 cbc
8 dbc
9 xyz
10 xyz
11 abc
12 abc

그 다음에

$ grep -zPo '.*abc(?s)(?(?!abc).)*?xyz' file
5 abc
6 bbc
7 cbc
8 dbc
9 xyz

답변3

tac file | sed '/xyz/,/a/!d' | tac

(그렇지 않으면 tac명령 에 동일한 작업을 수행 tail하는 명령이 있을 수 있습니다 .)-r

답변4

출력에 빈 줄이 있는지 신경 쓰지 않는다면 다음을 시도해 보십시오.

$ awk '
    !NF { next }
    /a/ { flag = 1; last = $0; next }
    last && flag { print last; print; last = 0; next}
    /xyz/ { print; flag = 0; next}
    flag
' file
5 a
6 b
7 c
8 d
9 xyz
10 xyz

관련 정보