Al, this is a little doc, with some pseudo code, of a sed implementation. The idea, is when people (that knows sed), has a question or need some fine tunning, to quickly answered themselves. One particulary example, are the strange behaviors of D, and a\ (well, sort of). As a last note remark, I am revieing my scripts packages, and also some documentation on sed (do-it-with-sed, advanced-sed, hints-sed? or sed-fine-tunning). This should be ok on august. For now (upto end of july), I will not (probably), dedicate any time to that. So, there goes the text. ADDRESSES ========= (0) no address, just the command per se (1) a single address or none, is permitted (2) a single address, a double address, or none is permitted any address, if specified, may be a number -- specifies the input line number, or a regular expression -- specifies all pattern spaces, that matches it. one address, appears per se, before the command two addresses, appears separated per a comma `,' if an address is omitted, the command will be apllied on all pattern spaces that passes through it y/a/b/ executes on all ps 3 y/a/b/ executes on ps which last line loaded, was 3 /foo/ y/a/b/ executes on ps that matches /foo/ 4,/foo/ y/a/b/ executes from ps which last line loaded was 4, up to, including, ps that matches /foo/ /foo/,5 y/a/b/ as above, but from /foo/ up to 5 COMMANDS MICROCODE ================== notes: - first, everything begins with a (sic) `goto [end]', after all variables have been zeroed/offed/emptyed - all commands, have a `pop ps' and a `push ps', to enforce that they really operate on patern space - the `print ps to stdout' "microcode" below, prints an extra newline after the print the `ps' itself [end] . pop ps . if not nflag and line_counter>=1, print ps to stdout . print append_buffer to stdout (which might be empty) . empty append_buffer . set tflag off (see s, t) . if come_from_D . set come_from_D off (see D) . else . if no more input lines, exit . load next line into ps, increment line_counter . push ps . goto start (2) s/RE/replacement/[gp#w], #: 1-9 . pop ps . if # not given, or g given, #=1 . set last_match = begin of ps !! do not set tflag off (see t, [end]) [1] . repeat # searches for RE, on ps, from last_match to end . if found . tflag on . replace the found match, per `replacement' . if w file, append ps at end of `file' . if p, print ps to stdout . if g, set last_match to end of replacement+1 and goto [1] . push ps (2) y/list1/list2/ . pop ps . foreach character c1 on list1 . fetch character c2 from list2 . replace all occurrences of c1 per c2 . push ps (1)i\ text . print text to stdout immediatly (1)a\ text . collect (i.e append) text to append_buffer (see [end]) (2)c\ text . print text to stdout immediatly . pop ps . empty ps . push ps . goto [end] !! because ps is empty, the `print ps' at [end] will not produce output (1)r file . print contents of file, immediatly to stdout (2)w file . pop ps . append ps at end of file . push ps (0): label . name next command, as `label' (2)b label . goto command named `label' (2)t label . if tflag on (see s///) . set tflag off . goto command `label' (1)q . pop ps . if not nflag, print ps to stdout . print append_buffer (might be empty, which cause no output) . exit (2)p . pop ps . print ps to stdout . push ps (2)l . pop ps . copy ps to tmp . replace on tmp, some special characters, per their conventional equivalents \x . print tmp . push ps (1)= . print line_counter to stdout (2)n . if no more lines on input, goto [end] . pop ps . if not nflag, print ps to stdout . load next line into ps, increment line_counter . push ps !! and continues, does not jump to start, or end (2)d . pop ps . empty ps . push ps . goto [end] (2)h . pop ps . set hold_buffer as ps . push ps (2)H . pop ps . set hold_buffer to hold_buffer+\n+ps . push ps (2)g . pop ps . set ps as hold_buffer . push ps (2)G . pop ps . set ps as ps+\n+hold_buffer . push ps (2)x . pop ps . push hold_buffer . set hold_buffer as ps !! exchange hold buffer with pattern space (2)N . if no more lines on input, goto [end] . pop ps . load next line into tmp, increment line_counter . set ps to ps+\n+tmp . push ps !! and continues, does not jump to start, or end (2)P . pop ps . copy ps to tmp . print remove from first \n upto end . print ps to stdout . push tmp (2)D . pop ps . if ps does not contain a \n . empty ps . push ps . goto [end] !! i.e. does the same as `d' . remove from beginning of ps, upto, including, first \n . push ps . set come_from_D on (see [end]) . goto [end] !! do not load next line, if ps contained \n == Carlos Duarte, 980712