Using The ed(1) Text Editor

Getting Started

There's an old joke you've probably heard: "ed is the standard unix text editor", which is kind of a joke third-party position in the editor war. If you've ever gotten curious and run ed, probably something like this happened. In this transcript, as in all those below, lines starting with '$' are typed into the shell, lines starting with '%' are typed into ed, and lines with no prefix are emitted by ed.

$ ed % help ? % ? ? % quit ? % C ? % D $ rm /bin/ed

You'll notice that ed is extremely terse. It comes from the bad old days when each character of output had to come through a clunking line printer, so ed generally doesn't say anything it doesn't have to. Fortunately, ed has a 'helpful' mode, which you can turn on by typing 'H':

$ ed % H % help ? invalid command suffix

Ok, so it could be more helpful, but it's better than just '?' at least.

What is ed, anyway?

Like other editors, ed is oriented around editing "buffers", which might be backed by files or might just be kept in memory. At any given time, ed has only one buffer - there's no support for editing multiple documents simultaneously or anything similar.

Most editors are "visual editors", in which the editor always displays part of the contents of the buffer, and you can make edits directly to the displayed text. Some well-known visual editors are emacs and vim (which is actually a distant descendant of ed). In contrast, ed is a "line editor", in which the buffer isn't continuously displayed, and you edit the buffer by typing commands that manipulate the text in the buffer. For example, you might type a command for "delete the first four characters of line 3", and the editor would carry that out without displaying the actual text at any point. This makes ed quite friendly for low-bandwidth or low-resource systems.

Addressing

So, let's go about getting to grips with ed a bit. Since ed is a line editor, every ed command is tagged, either implicitly or explicitly, with which lines it's supposed to operate on. You can address lines a bunch of ways but the most common ways are:

Some commands implicitly operate on "." if no line number is given.

Adding Text

Each command in ed needs either zero addresses, for commands that affect the whole file, one address for commands that affect a single line, or two addresses for commands that affect a range of lines. Commands that take a line range can by given only one address, in which case the range is just that line. Here are some of the basic commands:

The i and a commands enter "insert mode", in which typed text is added to the buffer instead of being treated as a command - this feature made its way into vi and thence into some other editors. Typing "." on a line by itself exits insert mode.

Let's try these commands out a bit:

$ ed % 0a % Hello, ed tutorial readers! % % This is some text in insert mode. % Insert mode is ended with a ".". % . % 1,$n 1 Hello, ed tutorial readers! 2 3 This is some text in insert mode. 4 Insert mode is ended with a ".". % 3a % This is a line being appended after line 3. % . % 1,$n 1 Hello, ed tutorial readers! 2 3 This is some text in insert mode. 4 This is a line being appended after line 3. 5 Insert mode is ended with a ".".

Here we can see some examples of what adding text to a file is like. If we had run ed with a filename, it would have loaded that file into its initial buffer.

Editing Existing Text

There's a couple more things we're going to need, though. What if we make a mistake? Within a line, we can backspace and type new text, but already- typed lines need something else to edit them. Enter the d and s commands!

Let's play with the new toys a bit: $ ed % 0a % This is another example. % Oh, this line was a mistake! % And this line has a tyop. % . % 1,$n 1 This is another example. 2 Oh, this line was a mistake! 3 And this line has a tyop. % 2d % 1,$n 1 This is another example. 2 And this line has a tyop. % 2s/tyop/typo/ % 1,$n 1 This is another example. 2 And this line has a typo.

So here we can see how to delete whole lines and change individual parts of lines. We can also use the s command for other things, using the ability to address many lines:

$ ed % 0a % This is the first line. % This is the second line. % Is this the third line? % . % 1,$n 1 This is the first line. 2 This is the second line. 3 Is this the third line? % 1,$s/^/-> / % 1,\(s/\)/ <-/ % 1,$n 1 -> This is the first line. <- 2 -> This is the second line. <- 3 -> Is this the third line? <-

Here we're making good use of the two-address form of "s", using "1,\(" to mean "the first line to the last line" - i.e., the whole buffer. In fact, addressing the whole buffer is so common that there's a special address for it: "%" is a shortcut for "1,\)".

Loading and saving

So we've written some text in our buffer, but how do we actually save it? Enter the "w" command. The w command takes two addresses, but if no addresses are given it defaults to "1,$". It also takes a filename after the command, which is where the addressed lines are written to. If ed was started with a filename, "w" will default to writing to that filename if no filename is given with the command. It has a counterpart command, "r", which takes one address and reads the named file after the addressed line. Let's play with that:

$ ed % 0a % This is the first line. % This is the second one. It will look pretty in a file! % This is the third line. % . % 2,$w example.txt 79 % 3r example.txt 79 % 1,$n 1 This is the first line. 2 This is the second one. It will look pretty in a file! 3 This is the third line. 4 This is the second one. It will look pretty in a file! 5 This is the third line.

Note that after ed reads or writes a file, it says how many bytes it read or wrote.

Quitting

The last thing we need to learn how to do is quit! The "q" command quits ed, although it will error once if you have a buffer that hasn't been written - in that situation, running "q" again will quit ed anyway. Since writing to an edited file and quitting is a very common operation, some eds have a shortcut command "wq" that writes and quits.

So, let's review:

Quick Reference

Addressing:

Commands (address counts prefixed):

Common idioms: