Some differences between various versions of ed(1)
Today, the versions of ed(1)
that people are most likely to
encounter and experiment with are GNU ed on Linux,
and FreeBSD ed and
OpenBSD ed on their respective
systems. GNU ed is a new implementation written from scratch, while
I believe that the *BSD ed is a descendant from the original V7
ed
by way of 4.x BSD ed, such as 4.4BSD ed.
However, a great deal of what's said about ed(1)
, especially in
stuff from the 1980s, is basically about the original V7 ed. This
sort of matters because these various versions have added and changed
some things, so the experience with the original V7 ed
is not
quite the same as what you'd have today.
Every modern version of ed
offers a '-p
' flag that provides a
command prompt (and a P
command to toggle the prompt on and off,
with a default prompt of '*
'), but this is not in either V7 ed
or 4.4BSD ed. This idea appeared in some versions of ed
very
early; for example, in the early 1980s people at the University of
Toronto modified the early versions of ed
from V7 and 4.x BSD
into 'UofT ed', and one of its standard features was that it basically
always had a command prompt.
(As far as I know, UofT ed was strongly focused on interactive use, especially by undergraduate students.)
Line addressing is almost the same in all versions. All modern
versions support a bare ';
' to mean 'from here to the end of the
file', and the *BSD versions support a bare '%
' as an alias for
a bare ',
' (ie, 'the entire file'). Modern versions of ed
support
more regular expression features (such as character classes), but
unsurprisingly haven't changed the basics. GNU ed has the most
features here, but OpenBSD and FreeBSD turn out to differ slightly
from each other in their choices for some syntax.
GNU ed has the most additions and changes in commands. It's the
only ed
that has a cut buffer for transferring content between
files (the x
and y
commands), #
as a comment command, and it
has various options to print out lines that a s
command has acted
on.
Compared to modern versions of ed
, V7 ed and 4.4BSD ed don't have
a version of the e
, r
, or w
commands that run a program instead
of using a file (modern 'e !<command>
' et al), G
or V
commands
for interactively editing lines that match or don't match a regular
expression, the h
or H
commands to actually explain errors, or
the n
command to print lines with line numbers. V7 ed
doesn't
have either z
(to print the buffer in pages) or wq
, but 4.4BSD
ed has both. The V7 s
command is quite minimal, with no support
for printing out the lines that s
operated on; 4.4 BSD may have
some support for this, although it's not clearly documented. Both
V7 and 4.4BSD only let you substitute the first match or all matches
in the line; all modern ed
s let you substitute the Nth match if
you want. According to its manpage, V7 ed
would let you do a q
or e
with a modified buffer without any warning; everything else
warns you and requires you to do it again. V7 ed
also has a limited
u
command that only applies to the last line edited; from 4.4BSD
onward u
was extended to undo all effects of multi-line commands
like d
and g
.
Update: V7 ed
has the E
command, which implicitly mentions that
ed
does warn you on e
with a modified buffer; I suspect it also
warns you on a q
. It's just that V7 doesn't feel that this needs
to be mentioned in the manpage. Everyone else documents it explicitly.
In general, modern versions of ed
are more friendly and powerful
than the original V7 ed and even than 4.4BSD ed, but they probably
aren't substantially so. The experience of using ed today is thus
pretty close to the original V7 experience, especially if you don't
turn on a prompt or extended help information about errors.
I was actually a bit surprised by how relatively little ed
has
changed since V7, and also how comparatively much has changed since
4.4 BSD. Apparently a number of people in both the *BSDs and GNU
really cared about making ed
actively friendlier for interactive
editing, since prompts and more help only appear after 4.4BSD.
(I suspect that modern versions of ed
can edit larger files and
ones with longer lines than the original V7 ed
, but you probably
don't want to do that anyway. V7 ed
appears to have had some
support for editing files larger than could fit easily in memory,
judging by some cautions in its manpage.)
Sidebar: UofT ed
Now that I've carefully read its manpage, UofT ed is an interesting
departure from all of this. It has a number of additions to its
regular expressions; '\!
' matches control characters apart from
tabs, '\_
' matches a non-empty sequence of tabs and spaces,
'\{
' and '\}
' match the start and end of 'identifiers', '\?
'
is a shortest-match version of '*
', and it has '|
' for regular
expression alternation, which not even GNU ed has opted to add. In
line addressing, UofT ed added '&
', which means 'a page of lines'.
For commands, it added b
which is essentially the modern z
, a
h
command to print help on the last error message or on various
topics, a o
command to set some options including whether regular
expressions are case-independent, and a special z
'zap' command
that allows 'interactive' modification of one line. It also supports
!
in e
, r
, and w
and allows specifying which match to use
in s
expressions.
The UofT ed zap command is especially interesting because it's an
attempt to provide a visual way of modifying a line without departing
from ed
's fundamental approach to editing; in other words, it's
an attempt to deal with ed's fundamental limitation. I'm going to quote the start of the manpage's
documentation to give you the flavour:
The zap command allows one line at a time to be modified according to graphical requests. The line to be modified is typed out, and then the modify request is read from the terminal (even if the z command is in a global command); this is done repeatedly until the modify request is empty. Generally each character in the request specifies how to modify the character immediately above it, in the original line, as described in the following table.
Zap allows you to delete characters, replace them, overwrite or
insert characters, or replace the entire rest of the line with
something else, and you could iterate this until you were happy
with the result. Because I can, here is an authentic example of
z
in action:
; ed [...] *p abc def ghi *z abc def ghi #### abc ghi ^def def abc ghi fred def abc fred $afunc(a, b) def afunc(a, b) *
This is a kind of silly example, but you can see how we can
successively modify the line while still being able to see what
we're doing. This is an especially clever approach because ed
(the program) doesn't have to switch to character at a time input
to implement it; ed
is still reading a line at a time, but it's
created a way where you can use this visually.
(Interested parties are encouraged to implement this for GNU ed,
and if you are one I can give you a complete description of the
various characters for z
. You'd have to pick another command
letter, though, since modern ed
s use z
for paginated output
of the buffer.)
Comments on this page:
|
|