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:
%s/regexp/substitution/
%p
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.
-
sed is Turing-complete, so as a second approximation it is a game of Tetris ↩
-
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 ifsed
can be forced to turn itself inside-out like that. ↩ -
but only somewhat familiar.
ed
is a line-oriented editor, so for example thed
command means "delete the current line" which invim
would bedd
. 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 uses/.../.../
. ↩
Top comments (1)
I have used
sed
several times, but have never even thought to useed
.