시작 패턴과 끝 패턴 사이의 마지막 줄 시퀀스를 인쇄하는 방법은 무엇입니까?

시작 패턴과 끝 패턴 사이의 마지막 줄 시퀀스를 인쇄하는 방법은 무엇입니까?

이 질문에 대한 답변:

시작 패턴과 끝 패턴 사이의 줄을 찾는 방법은 무엇입니까?

일치하는 패턴 사이의 여러 행 시퀀스는 신경 쓰지 않습니다. 예를 들어, sed -n '/startpattern_here/,/endpattern_here/p'이러한 패턴이 나타나는 사이에 일련의 여러 줄이 인쇄됩니다.

하지만 그냥 인쇄하고 싶다고 가정해 보겠습니다.마지막파일에 이러한 순서가 있습니다. sed를 사용하여 이 작업을 수행할 수 있나요? 그렇지 않다면 아마도 이상할 것 같은데요? 다른 건 없나요?

노트:

  • 이러한 시퀀스는 겹치지 않는다고 가정할 수 있습니다.
  • 시작 및 끝 패턴 라인~해야 한다출력에 포함됩니다.
  • 복잡성이 낮은 패턴을 가정하는 답변도 유효합니다(최적은 아니지만).

답변1

전체 정규식 테스트를 원한다고 가정하면 다음과 같이 작동할 수 있습니다.

awk '/startpattern_here/ {buf="";f=1}
     f{buf=buf $0 "\n"}
     /endpattern_here/ {f=0; lastcomplete=buf}
     END{printf("%s",lastcomplete)}' file.txt

이렇게 하면 완전한 시작-중지 패턴만 인쇄됩니다.

테스트 사례:

irrelevant
irrelevant
irrelevant
startpattern_here
relevant_but_dont_show_1
relevant_but_dont_show_1
relevant_but_dont_show_1
endpattern_here

irrelevant
irrelevant
 
startpattern_here
relevant_but_dont_show_2
relevant_but_dont_show_2
relevant_but_dont_show_2
endpattern_here

irrelevant
irrelevant

startpattern_here
relevant_and_show
relevant_and_show
relevant_and_show
endpattern_here

irrelevant
startpattern_here
incomplete_dont_show

결과:

startpattern_here
relevant_and_show
relevant_and_show
relevant_and_show
endpattern_here

노트시작 모드와 종료 모드의 출력을 억제하려면 sums 규칙을 바꾸면 됩니다 /startpattern_here/ { ... }. /endpattern_here/ { ... }즉, "종료 모드" 규칙을 먼저 배치한 다음 END그 앞에 "시작 모드" 규칙을 배치하면 됩니다.

답변2

tac과 awk의 조합

tac file \
| awk '
   !p && /endpattern_here/   {p = 1}
    p                        {print}
    p && /startpattern_here/ {exit}
' \
| tac

답변3

그리고전임자(POSIX 편집기) 매우 간단합니다.

printf '%s\n' 1 '?END?' '?START?,.p' | ex -s file
  • 1파일의 첫 번째 줄로 이동합니다. 이는 파일의 마지막 줄인 경우 END필요합니다 .

  • ?END?파일의 끝 부분에서 뒤로 검색하여 END파일에서 마지막으로 나타나는 항목을 찾습니다.

  • ?START?,.pSTART이전 주소부터 현재 주소까지 모두 인쇄합니다 .

printf다음은 다양성을 위해 here-docs를 대신 사용하는 예입니다 .

$ cat file
zdk
START
b12
END
kdn
START
000
111
END
START
ddd
$ ex -s file <<EOF
> 1
> ?END?
> ?START?,.p
> EOF
START
000
111
END

답변4

한 가지 방법은 단순히 각 그룹을 저장하고 다음 그룹으로 덮어쓴 다음 끝에 도달하면 유지한 그룹을 인쇄하는 것입니다.

awk '{ 
        if(/startpattern_here/){
            a=1; 
            lines=$0; 
            next
        } 
        if(a){
            lines=lines"\n"$0
        } 
        if(/end_pattern/){
            a=0
        }
    } 
    END{
        print lines
    }' file

예를 들어 다음 테스트 파일을 사용합니다.

startpattern_here
line 1
line 2
line 3
end_pattern
startpattern_here
line 1b
line 2b
line 3b
end_pattern
startpattern_here
line 1c
line 2c
line 3c
end_pattern

나는 얻다:

$ awk '{ if(/startpattern_here/){a=1; lines=$0; next} if(a){lines=lines"\n"$0} if(/end_pattern/){a=0}} END{print lines}' file
startpattern_here
line 1c
line 2c
line 3c
end_pattern

관련 정보