One of the things that is frequently said about
ed(1)
is that it remains useful for non-interactive modifications to files, for example as part of shell scripts. I even mentioned this as a good use of
ed
today in my entry on why
ed
is not a good (interactive) editor today , and I stand by that. But, well, there is a problem with using
ed
this way, and that problem is why I only very rarely actually use
ed
for scripted modifications to files.
The fundamental problem is that non-interactive editing with
ed
has no error handling . This is perfectly reasonable, because
ed
was originally written for interactive editing and in interactive editing the human behind the keyboard does the error handling, but when you apply this model to non-interactive editing it means that your stream of
ed
commands is essentially flying blind. If the input file is in the state that you expected it to be, all will go well. If there is something different about the input file, so that your line numbers are off, or a '
/search/
' address doesn't match what you expect (or perhaps at all), or any number of other things go wrong, then you can get a mess, sometimes a rapidly escalating one, and then you will get to the end of your
ed
commands and '
w
' the resulting mess into your target file.
As a result of this, among other issues,
ed
tends to be my last resort for non-interactive edits in scripts. I would much rather use
sed
or something else that is genuinely focused on stream editing if I can, or put together some code in a language where I can include explicit error checking so I'll handle the situation where my input file is not actually the way I thought it was going to be.
(If I did this very often, I would probably dust off my Perl.)
If I was creating an ideal version of
ed
for non-interactive editing, I would definitely have it include some form of conditionals and 'abort with a non-zero exit status if ...' command. Perhaps you'd want to model a lot of this on what
sed
does here with command blocks,
b
,
t
(and
T
in GNU sed), and so on, but I can't help but think that there has to be a more readable and clear version with things like relatively explicit if conditions.
(I have a long standing
sed
script that uses some clever tricks with
b
and the pattern space and so on. I wrote it in
sed
to deliberately explore these features and it works, but it's basically a stunt and I would probably be better off if I rewrote the script in a language where the actual logic was not hiding in the middle of a Turing tarpit .)
PS: One place this comes up, or rather came up years ago and got dealt with then, is in what
diff
format people use for
patch
. In theory you can use ed scripts; in practice, everyone considers those to be too prone to problems and uses other formats. These days, about the only thing I think ed format diffs are used for is if you want to see a very compact version of the changes. Even then I'm not convinced by their merits against '
diff -u0
', although we still use ed format diffs in our worklogs out of long standing habit.
Sidebar: Where you definitely need
ed
instead of
sed
The obvious case is if you want to move text around (or copy it), especially if you need to move text backwards (to earlier in the file). As a stream editor,
sed
can change lines and it can move text to later in the file if you work very hard at it, but it can never move text backward. I think it's also easier to delete a variable range of lines in ed, for example 'everything from a start line up to but not including an end marker'.
Ed will also do in-place editing without the need to write to a temporary file and then shuffle the temporary file into place. I'm neutral on whether this is a feature or not, and you can certainly get
ed
to write your results to a new file if you want to.