Hands up who's heard of the
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?
ed. It is a direct ancestor of
sed can do everything that
ed you can do things like this2:
some_command | ed -s somefile | other_command
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
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
sed -f /dev/stdin. Shush.
edfeels more editory anyway, which (at least for me) is a good enough reason to use it even if
sedcan be forced to turn itself inside-out like that. ↩
but only somewhat familiar.
edis a line-oriented editor, so for example the
dcommand means "delete the current line" which in
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