Description
  • The datafile consists of blocks and separating lines.
  • The first line of every block is of the form interface name. Every remaining line of a block begins with non-exclamation-mark character.
  • A separating line consists of only one character: the exclamation mark('!').
We want to add a trailing line end-of-block after each block.
Raw Input Desired Output
!
!
interface Loopback0
 ip address 10.6.6.190 255.255.255.252
!
interface GigabitEthernet5/1
 ip address 10.6.7.234 255.255.255.252
 ip access-group 113 in
 ip access-group 113 out
!
interface GigabitEthernet5/2
 ip address 10.6.8.238 255.255.255.252
 ip access-group 113 in
 ip access-group 113 out
!
!
!
interface Loopback0
 ip address 10.6.6.190 255.255.255.252
end-of-block
!
interface GigabitEthernet5/1
 ip address 10.6.7.234 255.255.255.252
 ip access-group 113 in
 ip access-group 113 out
end-of-block
!
interface GigabitEthernet5/2
 ip address 10.6.8.238 255.255.255.252
 ip access-group 113 in
 ip access-group 113 out
end-of-block
!
Script and Comments
Script1
[ 1] /^interface/!b
[ 2] :loop
[ 3] $!{
[ 4] N
[ 5] /\n!$/!b loop
[ 6] }
[ 7] s/\n!$/\nend-of-block&/
Comments
  1. If a line does not belong to a block, command 'b' will make sed branch to the end of the script, print that line, and start the next cycle.
  2. When the current line begins with 'interface', the loop consists of steps [2] thru [5] will append the following lines to Pattern Space (PS) until a
  3. line beginning with '!' or the end of datafile is reached.
  4. Step [7] is used to add a trailing line after each block.
  5. This script will NOT add a trailing line to the last block if is it not followed by any separating line; this can be improved by rewriting Step [7] to any of the following:
    • s/\(\n!\)*$/\nend-of-block&/, or
    • s/(\n!)*$/\nend-of-block&/, if the '-r' option of sed is used, or
    • s/(\n!)?$/\nend-of-block&/, if the '-r' option of sed is used.
    Note that '-r' option of GNU sed will make it interpret REs as EREs.