sed 여러 줄 재귀 패턴 교체

sed 여러 줄 재귀 패턴 교체

다음에서 입력:

serial0/0
SSL disabled
eth0/0
SSL enabled
SSL only
eth0/1
SSL disabled
bgroup0
SSL enabled
eth0/2
SSL disabled
eth0/3
SSL disabled
eth0/4
SSL disabled
bgroup1
SSL disabled
bgroup2
SSL disabled
bgroup3
SSL disabled
vlan1
SSL enabled
null
SSL disabled

다음 입력 줄이 "SSL"로 시작하면 이전 줄에 추가되어 출력이 다음과 같이 표시되는 콜론으로 구분된 목록을 얻으려고 합니다.

serial0/0:SSL disabled
eth0/0:SSL enabled:SSL only
eth0/1:SSL disabled
bgroup0:SSL enabled
eth0/2:SSL disabled
eth0/3:SSL disabled
eth0/4:SSL disabled
bgroup1:SSL disabled
bgroup2:SSL disabled
bgroup3:SSL disabled
vlan1:SSL enabled
null:SSL disabled

이 이상적인 출력의 두 번째 줄에서 볼 수 있듯이 "SSL"로 시작하는 여러 줄을 고려해야 합니다. 기반으로이것클래식 sed가이드에서는 다음 스크립트를 생각해 냈습니다 sed.

sed -r '/^SSL/! {
        :again
        N
        s/(.*)\n(SSL.*)/\1:\2/
        t again
    }'

이것은 나에게 의미가 있지만 다음 출력을 반환합니다.

serial0/0:SSL disabled
eth0/0
SSL enabled
SSL only
eth0/1:SSL disabled
bgroup0
SSL enabled
eth0/2:SSL disabled
eth0/3
SSL disabled
eth0/4:SSL disabled
bgroup1
SSL disabled
bgroup2:SSL disabled
bgroup3
SSL disabled
vlan1:SSL enabled
null
SSL disabled

내가 뭘 잘못하고 있는지 아시나요?

답변1

더 간단한 솔루션:

sed -z 's/\nSSL/:SSL/g'

NUL을 줄 구분 기호로 사용한다고 합니다 -z. 즉, 전체 스트림을 효과적으로 한 줄로 표시하게 됩니다 sed. 그런 다음 \nSSL한 시퀀스를 :SSL다른 시퀀스로 간단히 대체하여 원하는 방식으로 라인을 효과적으로 결합할 수 있습니다 .

답변2

sed전체 파일을 메모리에 넣지 않고도 어떤 스타일이든 사용할 수 있습니다 . 일반적인 N;P;D루프와 분기를 사용하면 됩니다.

sed ':b;$!N;s/\nSSL/:SSL/;tb;P;D' infile

N이것은 ext 라인을 가져와 s교체를 시도합니다. 성공하면 :belse 로 다시 분기하여 P인쇄한 다음 D개행 문자까지 삭제하여 루프를 다시 시작합니다.

관련 정보