처리해야 하는 여러 줄의 로그 항목 형식이 있습니다.
로그는 다음과 같습니다.
--START--
Device=B
Data=asdfasdf
Lorem=Ipsum
--END--
--START--
Device=A
Data=asdfasdf
Lorem=Ipsum
--END--
--START--
Device=B
Data=asdfasdf
--END--
--START--
Device=A
Data=asdfasdf
--END--
--START--
Device=B
Data=asdfasdf
--END--
--START--
Device=C
Data=asdfasdf
Lorem=Ipsum
--END--
특정 패턴이 일치하는 경우 --START--
사이의 모든 내용을 인쇄하고 싶습니다 .--END--
예를 들어:
모든 항목 인쇄Device=A
--START--
Device=A
Data=asdfasdf
Lorem=Ipsum
--END--
--START--
Device=A
Data=asdfasdf
--END--
지금까지 내가 할 수 있는 일은 다음과 같이 쓰는 것 뿐이다.
sed -e -n '/--START--/,/--END--/p' < input
{}
입력값을 효과적으로 출력하는데, 필터를 추가 N
한 뒤 조건이 일치하면 출력 해야 할 것 같습니다 .
나도 완전히 길을 잃은 것 같은 느낌이 든다.
한 줄이 조건과 일치하는 경우 여러 줄을 인쇄하는 방법을 알고 있습니까?
답변1
$ sed -n '/--START--/{:a;N;/--END--/!ba; /Device=A/p}' file
--START--
Device=A
Data=asdfasdf
Lorem=Ipsum
--END--
--START--
Device=A
Data=asdfasdf
--END--
(위 내용은 GNU sed에서 테스트되었습니다. BSD/OSX에서 실행되도록 조정해야 합니다.)
작동 방식:
/--START--/{...}
포함된 행에 도달할 때마다
--START--
중괄호 안의 명령이 실행됩니다{...}
.:a
라벨을 정의합니다
a
.N
다음 줄을 읽고 패턴 공간에 추가하세요.
/--END--/!ba
패턴 공간에 현재 레이블이 포함되어 있지 않으면
--END--
레이블로 다시 이동합니다a
./Device=A/p
여기까지 오면 패턴 공간이 로 시작
--START--
하고 으로 끝난다는 뜻입니다--END--
. 추가적으로, 패턴 공간에 그것이 포함되어 있다면Device=A
, 그것을 인쇄(p
)하세요.
답변2
sed
예약된 공간을 사용한 기타 변형
sed 'H #add line to hold space
/--START--/h #put START into hold space (substitute holded in)
/--END--/!d #clean pattern space (start next line) if not END
x #put hold space into pattern space
/Device=A/!d #clean pattern space if it have not "Device=A"
' file
답변3
그리고 sed
:
$ -e:1 -e'$!N;/--END--/{
/Device=A/!d
b
}' -eb1 <file
--START--
Device=A
Data=asdfasdf
Lorem=Ipsum
--END--
--START--
Device=A
Data=asdfasdf
--END--
--START--
그러면 패턴 공간 사이와 패턴 공간 사이의 모든 줄이 읽혀집니다 --END--
. 일치하면 --END--
패턴 공간에 포함되어 있지 않은지 확인하고 Device=A
삭제하고, 그렇지 않으면 sed
패턴 공간을 인쇄하고 다음 루프를 시작합니다.
그리고 awk
:
awk '
/--START--/ {
getline d
if (d ~ /Device=A/) {
p = 1
printf "%s\n%s\n", $0, d
next
}
}
p
/--END--/ { p = 0 }
' <file
답변4
여기에는 문자열 사이의 문자열을 테스트하는 방법을 보여주는 몇 가지 다른 좋은 답변이 이미 있습니다.--START--
그리고--END--
그러나 예제 입력을 고려하면 실제로 걱정할 필요는 없습니다.--START--
별말씀을요.
sed -n '$!N;/^Device=A\n/,/\n--END--/P;D'
...모든 것을 인쇄합니다Device=A
\n
다음 항목이 발생할 때까지 발생하는 마지막 Ewline--END--
각 블록에. 괜찮아요--START--
굳이 확인할 필요는 없을 것 같기 때문이다.
따라서 다음과 같은 블록의 경우:
--START--
Device=A
...stuff...
--END--
...출력은 다음과 같습니다.
Device=A
...stuff...
...하지만 이런 블록의 경우에는...
--START--
Device=B
Device=A
...stuff...
--END--
...같은 결과가 출력됩니다.
N
마지막 줄이 아닌 모든 줄 에 추가 입력 줄을 추가하여 작동하므로 패턴 공간은 다음과 같습니다.!
$
^line1\nline2$
시퀀스 사이에 발생하는 모든 패턴 공간에 대해^Device=A\n
그리고\n--END--
현재 패턴의 두 줄 중 첫 번째 줄이 P
인쇄된 후 D
삭제되고 나머지 내용으로 다음 루프가 시작됩니다. 다음 패턴 공간은 다음과 같습니다.
^line2\nline3$