![첫 번째 일치하는 괄호 사이의 내용을 인쇄합니다.](https://linux55.com/image/186164/%EC%B2%AB%20%EB%B2%88%EC%A7%B8%20%EC%9D%BC%EC%B9%98%ED%95%98%EB%8A%94%20%EA%B4%84%ED%98%B8%20%EC%82%AC%EC%9D%B4%EC%9D%98%20%EB%82%B4%EC%9A%A9%EC%9D%84%20%EC%9D%B8%EC%87%84%ED%95%A9%EB%8B%88%EB%8B%A4..png)
입력 예:
START{
some text
{
more text}
almost there
}
nothing important{
...
원하는 출력:
START{
some text
{
more text}
almost there
}
첫 번째 여는 브래킷은 다른 위치에 있을 수 있습니다.
START{...
START {...
START
{...
시작 부분에는 특수 문자가 포함될 수도 있습니다. 예: *
{}
START부터 시작하는 모든 내용과 첫 번째 일치 사이의 모든 내용 (bash) 을 인쇄하고 싶습니다 . 나는 그것이 발견되면 증가 {
하고 발견되면 감소 하는 카운터를 가질 생각입니다 }
. 결과가 0이면 인쇄를 중지합니다(중괄호는 항상 일치함).
답변1
모든 Unix 시스템의 모든 쉘에서 어떤 awk에서도 작동하는 간단한 무차별 방법:
$ cat tst.awk
s=index($0,"START") { $0=substr($0,s); f=1 }
f { rec = rec $0 RS }
END {
len = length(rec)
for (i=1; i<=len; i++) {
char = substr(rec,i,1)
if ( char == "{" ) {
++cnt
}
else if ( char == "}" ) {
if ( --cnt == 0 ) {
print substr(rec,1,i)
exit
}
}
}
}
$ awk -f tst.awk file
START{
some text
{
more text}
almost there
}
답변2
그리고 pcregrep
:
start_word='START'
pcregrep -Mo "(?s)\Q$start_word\E\h*(\{(?:[^{}]++|(?1))*+\})" < your-file
zsh
내장된 기능을 사용하십시오 :
set -o rematchpcre
start_word='START'
[[ $(<your-file) =~ "(?s)\Q$start_word\E\h*(\{(?:[^{}]++|(?1))*+\})" ]] &&
print -r -- $MATCH
(?1)
위에서 검토한 첫 번째 쌍 (...)
의 정규식인 PCRE의 재귀 정규식 기능을 사용합니다 .
pcregrep
둘 다 없으면 zsh
언제든지 다음으로 전환할 수 있습니다.진짜( PCRE perl
에서 P
):
perl -l -0777 -sne '
print $& if /\Q$start_word\E\h*(\{(?:[^{}]++|(?1))*+\})/s
' -- -start_word='START' < your-file
( perl
이 중 하나를 제외하고 모두 $start_word
포함되지 않는 것으로 가정합니다 \E
.)