# overstrk.sed - implement the overstrike printer control function. # Created by E.Clay Buchanan Oct 27, 2002 # # All lines start with a printer control character. The overstrike # printer control character is a plus sign, +. All nonblank characters # on the overstrike line overwrite the character on the previous line at # the same column position except for the overwritten lines printer # control character which is preserved. # # The pattern space buffer is loaded with two lines. If line 2 is an # overstrike line the plus sign is replaced with a blank to preserve # the original lines printer control character. Then an empty merge # buffer is created by inserting a newline at the front of pattern # space giving: ^\n\n$ # # One by one, move either a character from line 2 (if non blank) or # from line 1 to the merge buffer until the end of line 1 or line 2 is # reached. Delete the newline character at the end of the merge buffer # and at the end of line 1 effectively appending the remaining text from # line 1 or 2 with the merge buffer. This leaves one overstruck line in # pattern space. Append the following line into pattern space and # repeat. # # ---------------------------------------------------------------------- # # To: sed-users@yahoogroups.com # From: "ecbyahoo" # Data: Tue, 29 Oct 2002 21:06:36 -0000 # Assunto: Re: Subject: how to superimpose several lines # # [...] # I created the general overstrike problem: # # The input file consists of a series of records with the first # character of each record being a printer control character. In # the case of an overstrike printer control character, a "+", # the previous line is overstruck with all nonblank characters # from the current line maintaining all column positions and # maintaining the previous line's printer control character. # There is no limit on the number of overstrike records. # # The following input file, input.txt: # # 111 # + 222 # 333 # +444 # 555 # +666 # 7 7 7 # + 8 8 8 # 999 # +888 # +777 # +666 # 1 1 1 # + 22 22 22 # + 3 3 3 # -222 # + 333 # # should produce the result: # # 1222 # 4443 # 666 # 787878 # 666 # 123123123 # -22333 # # The following sed command line: # # sed -f overstrk.sed # # where overstrk.sed is: :top N # always have two lines in pattern space /\n+/{ # was second line an overstrike line? s/\n+/\n / # yes, delete plus sign s/^/\n/ # create merge buffer at start of pattern space :merge s/^\(.*\)\n.\(.*\n\)\([^ ]\)\(.*\)$/\1\3\n\2\4/;tmerge #overstrike s/^\(.*\)\n\(.\)\(.*\n\) \(.*\)$/\1\2\n\3\4/;tmerge #do not s/\n//g # combine merged buffer with remaining line 1 or 2 btop } P # print line D # delete first line, repeat till done # does the job. Many thanks to aurelio for his sed debugger! # # ------------------------------------------------------------------------- # # Aurelio posted a GNU sed 3.02 working version (no s//\n/): # # :top # N ;# always have two lines in pattern space # /\n+/{ ;# was second line an overstrike line? # s/\(\n\)+/\1 / ;# yes, delete plus sign # H;s/.*//;x ;# create merge buffer at start of pattern space # :merge # s/^\(.*\)\(\n\).\(.*\n\)\([^ ]\)\(.*\)$/\1\4\2\3\5/;tmerge ;#overstrike # s/^\(.*\)\(\n\)\(.\)\(.*\n\) \(.*\)$/\1\3\2\4\5/;tmerge ;#do not # s/\n//g ;# combine merged buffer with remaining line 1 or 2 # btop # } # P ;# print line # D ;# delete first line, repeat till done