Using the `ed` editor

drhyde profile image David Cantrell ・3 min read

Hands up who's heard of the ed editor.


OK, that's a few of you. Now keep your hand up if you've used it, for anything more than just to see what it's about.


Oh, just me then. You're all missing out. It's a brilliant tool that, in a few limited circumstances, is exactly what you need.

You're all familiar with sed I assume? sed is the Stream EDitor, and to a first approximation1 it takes a small program and a file (or STDIN) as input, applies the program to every line of the file, and spits the results out one line at a time. A typical invocation looks like this:

sed 's/regexp/substitution/' input > output

That will replace any instance of regexp in the input data with substitution, and write the results to a new file.

Another typical invocation of sed looks like this:

some_command | sed 's/regexp/substitution/' | other_command

That is, we've got a pipeline where a program produces some output, we massage that output using a sed script, and pass the results on for further processing elsewhere.

But what if, instead of loading some pre-defined commands and feeding in some data, you want to load a file and feed in some editor commands? That is, instead of programatically producing the data, you want to programatically produce the commands?

Enter ed. It is a direct ancestor of sed, and sed can do everything that ed can do, but even so, in just the same way that Javascript can do everything that Python can do and vice-versa, sometimes a tool that specialises differently is what you want. Using ed you can do things like this2:

some_command | ed -s somefile | other_command

where some_command generates a program which ed then uses to transform the file. If we want to do the same transformation as we did a moment ago using ed instead of of sed then we'd do something like this:

printf "%s\n" %s/regexp/substitution/ %p | ed -s somefile | other_command

but of course the commands we feed in to ed can be anything you like, composed on the fly at run-time, which I think you'll agree makes it an elegant tool for a more civilized shell script. Let's break that command down.

ed -s somefile starts the editor with somefile already loaded; the -s tells it to be silent and suppress all output except when we explicitly tell it to say something. The printf command turns its arguments into two lines of text thus:


Those are then the STDIN to the ed command. And gosh, doesn't that first line look rather like a :command you might type into vim? The second line's %p means "for all lines (the %) print to STDOUT (p)" - in general any list of commands you pass to ed will end with %p or w, to write the edited file to STDOUT or to a file.

You can of course do anything else that the editors you are used to are capable of. I won't give you a full tutorial on it here (GNU's online documentation is a good place to start), but if you are a vi(m) user it will be somewhat familiar3, as the vi family of editors are, just like sed, descendants of ed too.

  1. sed is Turing-complete, so as a second approximation it is a game of Tetris 

  2. Yeah yeah, sed -f /dev/stdin. Shush. ed feels more editory anyway, which (at least for me) is a good enough reason to use it even if sed can be forced to turn itself inside-out like that. 

  3. but only somewhat familiar. ed is a line-oriented editor, so for example the d command means "delete the current line" which in vim would be dd. You don't navigate to a particular character and delete or add text, you navigate to a line and delete or add lines. To edit a line in-place you use s/.../.../


Editor guide
waylonwalker profile image
Waylon Walker

I have used sed several times, but have never even thought to use ed.