이 질문에 대한 답변:
시작 패턴과 끝 패턴 사이의 줄을 찾는 방법은 무엇입니까?
일치하는 패턴 사이의 여러 행 시퀀스는 신경 쓰지 않습니다. 예를 들어, 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?,.p
START
이전 주소부터 현재 주소까지 모두 인쇄합니다 .
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