4

From the following input:

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

I am trying to obtain a colon separated list in which if the next line of the input begins with "SSL", it gets appended to the previous line, so the output would be like so:

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

As you can see in the second line of this ideal output, the case when more than one line starts with "SSL" should be considered. Based on this classic sed guide, I came up with the following sed script:

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

Which makes sense to me but returns the following output:

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

Any idea of what I could be doing wrong?

8

A much easier solution:

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

The -z says to use NUL as a line separator - effectively making the entire stream appear as one line to sed. It then simple replaces a \nSSL sequence with a :SSL sequence, effectively combining lines the way you wish.

  • 4
    A large caveat to this solution is that it won't start processing anything until the input is terminated, which means if you're using it as part of a pipeline, you won't see any output from sed until the command providing the input to sed finishes. – John Aug 29 '16 at 18:10
5

You can do this with any sed flavor, no need to slurp the whole file into memory just use a classic N;P;D cycle and a branch:

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

This pulls in the Next line, attempts to substitute - if successful it branches back to :b else it Prints and then Deletes up to the newline character, restarting the cycle.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.