이 파일이 있습니다 :
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 문자까지 남겨두고 남아있는 것을 다시 시작합니다.\n
D
\n
물론, \n
패턴 공간에서 줄 바꿈을 하는 유일한 시간 은 입력 줄이 ^}
범위의 끝 과 일치 할 때뿐이므로 다른 경우에 스크립트를 다시 실행할 때 평소마다 다음 입력 줄을 가져옵니다.
경우 PATTERN
A와 동일한 패턴 영역에서 발견된다 \n
ewline하지만, 그것으로 덮어 쓰기 전에 많은 인쇄 ^}
다시 (그 범위를 중단하고 버퍼를 플러시 할 수 있으므로) .
이 입력 파일이 주어지면 (감사합니다) :
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
동일한 블록 안에있는 각 추가 줄에 대해 중복 된 출력을 얻습니다 . 예를 들어 두 개의 다른 섹션이 있는 테스트 파일의 경우 한 줄 일치하는
여러 항목에 대해 작동 합니다.{
}
PATTERN
PATTERN
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의 기본 동작을 억제했습니다.이 문장은 원하는 것을 정확하게 제공하지는 않지만 문자열을 바꿔야합니다.