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

この理想的な出力の2行目に示すように、「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。つまり、ストリーム全体を効果的に1行で表示しますsed。その後、\nSSLあるシーケンスを:SSL別のシーケンスに置き換えることで、目的の方法でラインを効果的に組み合わせることができます。

答え2

sedファイル全体をメモリに入れることなく、どのスタイルでも使用できます。一般的なN;P;Dループと分岐を使用してください。

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

Nこれはext行を取り、s交換を試みます。成功した場合は、:belseに再分岐してP印刷し、D改行文字まで削除してループを再開します。

関連情報