ed editor is a really good example of a sparse, minimal, standard
Unix tool that does one thing, and does it well. Because there are so many
good screen-oriented editors for Unix, there’s seldom very much call for using
ed, unless you’re working on very old or very limited hardware that won’t run
However, if part of the reason you use
vi is because you think it will always
be there (it may not be), then you should learn
ed too. If you’re using any
Unix at all, then
ed really will always be there, no matter how old or
limited the system. Well, unless you’re using Arch Linux. If your terminal is
vi won’t work, or you break it some other way, your choices may
well be between
Not a friendly editor
Even more than its uppity grandchild
ed has developed a reputation
as terse and intimidating to newcomers. When you type
ed at the command line,
nothing happens, and the only error message presented by default is
you’re reading this, it’s likely your first and only experience with
something like this:
$ ed help ? h Invalid command suffix ? ? ^C ? exit ? quit ? ^Z $ killall ed $ vi
ed is not a terribly intuitive editor. However, it’s not nearly as hard
to learn as it might seem, especially if you’re a veteran
vi user and thereby
comfortable with the
ex command set. With a little practice, you can actually
get rather quick with it; there’s an elegance to its almost brutal simplicity.
It’s also very interesting to learn how
ed works and how to use it, not just
because it might very well be useful for you one day, but because it occupies
an important position in the heritage of the
sed stream editor, the
vi visual editor, the
grep tool, and many other contexts.
ed so terse?
ed was developed, the usual method of accessing a Unix system was via
a teletype device, on which it wouldn’t have been possible to use
a screen-oriented editor like
vi. Similarly, modems were slow, and memory was
precious; using abbreviated commands and terse error messages made a lot of
sense, because the user would otherwise be wasting a lot of time waiting for
the terminal to react to commands, and didn’t have a whole lot of memory to
throw around for anything besides the buffer of text itself.
Of course, this is almost a non-issue for most Unix-like systems nowadays, so
one of the first things we’ll do is make
ed a little bit less terse and more
ed up the usual way:
We’ll start by deliberately doing something wrong. Type
b and press Enter:
There’s that tremendously unhelpful
? again. But if you press
h, you can
see what went wrong:
h Unknown command
Of course, since it’s the future now, we can spare the terminal cycles to have
ed print the error message for us every time. You can set this up by pressing
H b ? Unknown command
That’s a bit more useful, and should make things easier.
You can quit
q. Go ahead and do that. If you had unsaved changes in
a buffer, you could type
Q to quit unconditionally. Repeating yourself works
q ? Warning: buffer modified q
ed again, but this time we’ll use the
-p option to specify
a command prompt:
$ ed -p: :
We’ll use that from now on, which will make things clearer both for interpreting this tutorial and for remembering whether we’re in command mode, or entering text. It might even be a good idea to alias it:
$ alias ed='ed -p:'
Basic text input
We’ll start by adding a couple of lines of text to the new buffer. When you
ed with no filename, it starts an empty buffer for you, much like
Because there are no lines at all at present, press
a to start adding some at
the editor’s current position:
:a Start typing a few lines. Anything you want, really. Just go right ahead. When you're done, just type a period by itself. .
That’s added four new lines to the buffer, and left the editor on line 4. You
can tell that’s the case because typing
p for print, just by itself, prints
the fourth line:
:p When you're done, just type a period by itself.
A little more useful is
pn in some versions), which will show both
the line number and the contents of the line:
:n 4 When you're done, just type a period by itself.
So just like in
ex, the current line is the default for most commands. You
can make this explicit by referring to the current line as
:.n 4 When you're done, just type a period by itself.
You can move to a line just by typing its number, which will also print it as a side effect:
:3 Just go right ahead. :.n 3 Just go right ahead.
a like you did before will start inserting lines after the current
:a Entering another line. . :n 4 Entering another line.
i will allow you to insert lines before the current line:
:i A line before the current line. . :n 4 A line before the current line.
You can replace a line with
:c I decided I like this line better. . :n 5 I decided I like this line better.
You can delete lines with
And join two or more lines together with
You can prepend an actual line number to any of these commands to move to that line before running the command on it:
:1c Here's a replacement line. . :1n 1 Here's a replacement line.
For most of these commands, the last line to be changed will become the new current line.
You can select the entire buffer with
, for short (
% works too):
:,p Here's a replacement line. Just go right ahead. I decided I liked this line better. Entering another line.
Or a limited range of specific lines:
:2,3p Just go right ahead. I decided I liked this line better.
These ranges can include a reference to the current line with
:2 Just go right ahead. :.,4p Just go right ahead. I decided I liked this line better. Entering another line.
They can also include relative line numbers, prefixed with
:2 :-1,+1p Here's a replacement line. Just go right ahead. I decided I liked this line better.
You can drop a mark on a line with
k followed by a lowercase letter such as
a, and you’re then able to refer to it in ranges as
:3ka :'ap I decided I liked this line better.
Moving and copying
Move a line or range of lines to after a target line with
:1,2m$ :,p I decided I liked this line better. Entering another line. Here's a replacement line. Just go right ahead.
Copy lines to after a target line with
:2t4 :,p I decided I liked this line better. Entering another line. Here's a replacement line. Just go right ahead. Entering another line.
You can select lines based on classic regular expressions with the
operator. To print all lines matching the regular expression
:g/re/p Here's a replacement line.
(Hmm, where have I seen that command before?)
You can invert the match to work with lines that don’t match the expression
:v/re/p I decided I liked this line better. Entering another line. Just go right ahead. Entering another line.
Just like numbered line ranges, ranges selected with regular expressions can
have other operations applied to them. To move every line containing the
/re/ to the bottom of the file:
:g/re/m$ :,p I decided I liked this line better. Entering another line. Just go right ahead. Entering another line. Here's a replacement line.
You can move to the next line after the current one matching a regular
/. Again, this will print the line’s contents as a side
:/like I decided I like this line better.
You can search backward with
:?Here Here's a replacement line.
You can substitute for the first occurrence per line of an expression within
a range of lines with the
:1s/i/j I decjded I like this line better.
You can substitute for all the matches on each line by adding the
:1s/i/j/g :p I decjded I ljke thjs ljne better.
Reading and writing
You can write the current buffer to a file with
w, which will also print the
total number of bytes written:
:w ed.txt 129
Having done this once, you can omit the filename for the rest of the session:
w can be prefixed with a range to write only
a subset of lines to the file. This would write lines 1 to 4 to the file
:1,4w ed.txt 102
You can use
W to append to a file, rather than replace it. This would write
lines 3 to 5 to the end of the file
You can read in the contents of another file after the current line (or any
other line) with
r. Again, this will print the number of bytes read.
:r /etc/hosts 205
The output of a command can be included by prefixing it with
:r !ps -e 5571
If you just want to load the contents of a file or the output of a command
into the buffer, replacing what’s already there, use
E if you’ve got
an unmodified buffer and don’t care about replacing it:
:e ed.txt 173
If you don’t like seeing the byte counts each time, you can start
ed with the
-s option for “quiet mode”.
Almost all of the above command sets will actually be familiar to
who know a little about
ex, or Vimscript in Vim. It will also be familiar to
those who have used
sed at least occasionally.
Once you get good with
ed, it’s possible you’ll find yourself using it now
and then to make quick edits to files, even on systems where your favourite
screen-based editor will load promptly. You could even try using