Description
  • A block starts from a line beginning with <block>,
    and ends at a line beginning with </block>.
  • In the example, we want to get the second block of the datafile.
Raw Input Desired Output
line 1
line 2
<block>
block 1, line 1
block 1, line 2
block 1, line 3
</block>
line 8
line 9
<block>
block 2, line 1
block 2, line 2
</block>
line 14
<block>
block 3, line 1
</block>
line 18
<block>
block 2, line 1
block 2, line 2
</block>
Script and Comments
Script1
[ 1] /^<block>/,/^<\/block>/!d
[ 2] /^<block>/{
[ 3] x
[ 4] s/^/#/
[ 5] /^#{2}$/{
[ 6] x
[ 7] :loop
[ 8] n
[ 9] /^<\/block>/!b loop
[10] q
[11] }
[12] x
[13] }
[14] d
Comments -r
  1. To locate the block we want (in this case, the second one), we have to number each block by a counter, where
    • The value of the counter is stored in HS as the same number of hash signs (`#').
    • The initial value of the counter is zero.
    • Blocks are numbered from 1.
    • Each time the first line of a block is read, we increment the counter by one to get the block number.
  2. The counter is kept in HS, and the only way to edit HS is:
    • first exchange the contents of PS and HS, which can be done via command `x'.
    • then edit the contents of PS.
    • finally, exchange PS and HS again.
  3. Step [1] deletes lines not belonging to any block.
  4. When the first line of a block has been read to PS:
    • Step [2] matches.
    • Step [3] exchanges PS and HS.
    • Step [4] increment the counter by inserting a hash mark in the beginning.
    • If this block is what we want, the loop consisting of Steps [7] thru [9] prints all lines of the block except the last line,
      and Step [10] terminates sed after printing the last line of that block.