- 论坛徽章:
- 8
|
sed in (pseudo) microcode, by Carlos J. Duarte.
- sed in (pseudo) microcode, by Carlos J. Duarte.
- [ This article was posted to the seders mailing list ]
- 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
复制代码 |
|