Description
In the following example, we want to replace the last word with six dashes.
Raw Input Desired Output
word_1 word_2 word_3
more data...
word_4 word_5
more data...
word_6 word_7
word_8
more data...
word_9 final word_10
word_1 word_2 word_3
more data...
word_4 word_5
more data...
word_6 word_7
word_8
more data...
word_9 final ------_10
Script and Comments
Script1
[ 1] :0
[ 2] /word/!b
[ 3] :1
[ 4] $!N
[ 5] /\n.*word/{
[ 6] h
[ 7] s/\n[^\n]*$//p
[ 8] g
[ 9] s/^.*\n//
[10] }
[11] $!b 1
[12] s/^(.*)word/\1------/
Comments
  1. The `-r' option of GNU sed must be used or we have to escape the parentheses used in Step [12].
  2. Lines before and not including the one containing the first word are printed by an implicit loop consisting of Steps [1] thru [2].
  3. Once the line containing the first word is read, this script keeps reading lines and appending them to PS until
    • another line containing word is read or
    • the end of file is reached.
    This job is done by Steps [3] thru [11].
    If neither another line containing word is found nor the end of file is reached, \n.*word will not match PS at Step [5]. Therefore, sed skips to Steps [11], [3] then [4] to keep reading lines.
  4. Once another line containing word is read, we print and then delete all but the last line of PS by the following steps:
    • \n.*word matches PS at Step [5],
    • Step [6] copies the contents of PS to HS for later use,
    • Step [7] deletes the last line of PS then print the contents of PS,
    • Step [8] copies back the contents saved by Step [6],\
    • Step [9] deletes all but the last line of PS.
    • After Step [9], PS contains the most recently read line containing word. If it is not the last one, Step [10] makes sed jump to Step [3].
  5. When the last line of file is read, we are sure that the last word in PS is the last word of the file. We use Step [12] to replace the last word, note that there may be more than one words.