문자열을 검색하고 범위 내 전후의 모든 것을 인쇄 파일에서 특정 문자열을 검색하고이

이 파일이 있습니다 :

sometext1{
string1
}

sometext2{
string2
string3
}

sometext3{
string4
string5
string6
}

이 파일에서 특정 문자열을 검색하고이 문자열 앞의 {모든 것을 여는 부분까지,이 문자열 뒤의 모든 항목을 끝까지 인쇄하고 싶습니다 }. sed로 이것을 달성하려고했지만 범위의 모든 것을 인쇄하려고하면 /{/,/string2/sed가 이것을 인쇄합니다.

sometext1{
string1
}

sometext2{
string2
sometext3{
string4
string5
string6
}

문자열 “string2″를 검색하면 다음과 같은 출력이 필요합니다.

sometext2{
string2
string3
}

감사.



답변

다음은 두 가지 명령입니다. 당신은 마지막까지 트림 명령하려면 .*{$시퀀스에서 선을 (@don_crissti이와 마찬가지로 ed) 당신이 할 수 있습니다 :

sed 'H;/{$/h;/^}/x;/{\n.*PATTERN/!d'

… 이것은 ewline 문자 H다음에있는 모든 행을 이전 공간 에 추가하고 \n, h일치하는 모든 행의 이전 공간을 덮어 쓰고 {$, 일치하는 모든 행의 h이전 및 패턴 공간을 교체 ^}하여 버퍼를 플러시함으로써 작동합니다.

그것은 단지 일치하는 라인을 인쇄 {한 후 \n다음 ewline와 PATTERN어떤 점에서를 – 그리고 오직 즉시 버퍼 스왑을 다음 일어나는.

{$시퀀스의 마지막 행과 일련의 일치 하는 행을 제거 하지만 다음과 같은 것을 모두 얻을 수 있습니다.

sed '/PATTERN.*\n/p;//g;/{$/,/^}/H;//x;D'

그것이하는 일은 h모든 ...{$.*^}.*시퀀스에 대한 스왑 패턴과 이전 공백이며 , 시퀀스 내의 모든 라인을 ewline 문자 H다음의 오래된 공간에 추가하고 모든 줄주기마다 패턴 공간에서 처음 발생하는 ewline 문자까지 남겨두고 남아있는 것을 다시 시작합니다.\nD\n

물론, \n패턴 공간에서 줄 바꿈을 하는 유일한 시간 은 입력 줄이 ^}범위의 끝 과 일치 할 때뿐이므로 다른 경우에 스크립트를 다시 실행할 때 평소마다 다음 입력 줄을 가져옵니다.

경우 PATTERNA와 동일한 패턴 영역에서 발견된다 \newline하지만, 그것으로 덮어 쓰기 전에 많은 인쇄 ^}다시 (그 범위를 중단하고 버퍼를 플러시 할 수 있으므로) .

이 입력 파일이 주어지면 (감사합니다) :

sometext1{
string1
}

sometext2{
PATTERN
string3
}

sometext3{
string4
string5
string6
}

Header{
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}
}

첫 번째 인쇄 :

sometext2{
PATTERN
string3
}
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}

… 그리고 두 번째는 …

sometext2{
PATTERN
string3
}
Header{
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}

답변

다음과 같은 해결책이 있습니다 ed.

ed -s filename <<< $'g/PATTERN/?{?,/}/p\nq\n'

그건:

g/PATTERN/     # mark each line matching PATTERN
?{?,/}/p       # for each marked line, print all lines from the previous { up to the next }
q              # quit editor

이것은 PATTERN각 쌍 사이에 한 줄만 있다고 가정합니다. { }그렇지 않으면 PATTERN동일한 블록 안에있는 각 추가 줄에 대해 중복 된 출력을 얻습니다 . 예를 들어 두 개의 다른 섹션이 있는 테스트 파일의 경우 한 줄 일치하는
여러 항목에 대해 작동 합니다.{ }PATTERNPATTERN

sometext1{
string1
}

sometext2{
PATTERN
string3
}

sometext3{
string4
string5
string6
}

Header{
sometext4{
some string

string unknown

here's PATTERN again

another string here
}
}

달리는

ed -s sample <<< $'g/PATTERN/?{?,/}/p\nq\n'

출력 :

sometext2{
PATTERN
string3
}
sometext4{
some string

string unknown

here's PATTERN again

another string here
}

답변

pcregrep:

pcregrep -M '(?s)\{[^}]*PATTERN.*?\}'

또는 GNU grep에서 입력에 NUL 바이트가 포함되어 있지 않은 경우 :

grep -Poz '.*(?s)\{[^}]*PATTERN.*?\}'

답변

$ awk 'BEGIN{RS="\n\n"; FS="[{}]"} {if ($2 ~ /string4/) {print $2}}' t1.txt
string4
string5
string6

어디:

  • string4 -> 일치시킬 문자열
  • t1.txt -> 쿼리에 언급 된 파일 내용을 포함

답변

sed -n ‘/ 문자열 / p’ 파일 이름

sed에 추가 된 -n은 sed의 기본 동작을 억제했습니다.이 문장은 원하는 것을 정확하게 제공하지는 않지만 문자열을 바꿔야합니다.