문자열을 검색하고 범위 내 전후의 모든 것을 인쇄


9

이 파일이 있습니다 :

sometext1{
string1
}

sometext2{
string2
string3
}

sometext3{
string4
string5
string6
}

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

sometext1{
string1
}

sometext2{
string2
sometext3{
string4
string5
string6
}

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

sometext2{
string2
string3
}

감사.


글쎄, 나는 나중에 그것을 삭제하기 위해 원본 파일에 출력의 줄 번호가 필요하다는 것을 알았습니다. @mikeserv가 운없이 제공하는 명령을 변경하려고 시도했지만 sed의 hold 기능과 약간 혼동되었습니다.
rodrigo

글쎄요, 제 이즈, 당신은 누구에게도 말하지 않았어요. 할 수 있지만 다음과 같이하는 것이 가장 좋습니다 grep -n '' <infile | sed .... sed명령은 수정이 필요합니다; 특히 최상위 앵커 를 찾는 /주소 /비트 ^. 따라서 내 대답을 사용하는 경우 다음을 수행 할 수 grep -n '' | sed 'H;/{$/h;/^[^:]*:}/x;/{\n.*PATTERN/!d'있습니다.. 모든 출력 행은 원래 파일의 행 번호 앞에 콜론 등이 붙 1:sometext1{\n2:string1습니다. sed각 출력 라인이 숫자로 열리는 것을 제외하고는 이전에 필터링 한 것만 필터링합니다.
mikeserv

답변:


9

다음은 두 가지 명령입니다. 당신은 마지막까지 트림 명령하려면 .*{$시퀀스에서 선을 (@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
}

@ don_crissti-나는 몰라. 로 시작하는 행의 시퀀스 구분합니다 }. 이것은 다음과 같은 경우에 도움이 될 수 있습니다 ...- open{\nsub;\n{ command; }\n}; close그러나 그것이 현재 진행되고있는 것이 확실하지 않습니다 ...
mikeserv

안녕 @ mikeserv-나는 여기에 제기 된 비슷한 질문 unix.stackexchange.com/questions/232509/… , 귀하의 솔루션은 작은 파일에서 작동하지만 큰 파일이 있고 "홀드 스페이스 오버플로"가 발생합니다. 에러 메시지. 어쩌면 당신은 이것을 어떻게 해결할 수 있습니까? 많은 감사
Narayan Akhade

@NarayanAkhade-아뇨. 어쨌든 점검 없이는 아닙니다. 그렇지 않다면 ... {...}블록에 포함되지 않은 많은 양의 입력이 있습니까? 이 경우 첫 번째 솔루션을 사용하는 /{$/,/^}/H경우 시작 대신 그냥 수행 할 수 있습니다 H. 그러나 두 번째 솔루션을 시도했지만 여전히 동일한 오류가 발생하면 이미 그 일을하기 때문에 도움이되지 않습니다. 또한 할인하지 마십시오 ed. 돈의이있어 매우 여기에 좋은 답변을하고, ed임시 버퍼의 사용에 적용 할 수있는 파일을 MEM은 버퍼 오버런 방지해야하는 매우 간단뿐만 아니라.
mikeserv

6

다음과 같은 해결책이 있습니다 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
}

나는 이것에서 실제로 많이 가져 갔다! 매우 감사합니다!
mikeserv

나는이 명령이 존재한다는 것을 알지 못한다. 감사합니다
rodrigo December

4

pcregrep:

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

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

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

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

어디:

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

-2

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

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.