For all those little papers scattered across your desk
I stand for the Constitution, for due process, and for community that takes care of each other.
Right tool for the job people, right tool for the job
I’m referring to all the use of sed -i
spread wantonly on the internet, sans
appropriate caveats.
Background: most implementations of the
-i
flag allowsed
to edit files in place; by default, it edits standard in and writes to standard out, so you end up having to do<file sed ... >file.new && mv file.new file
. Trying to redirect back into the file (<file sed ... >file
) fails because the file is truncated beforesed
gets to read it!
The -i
flag is not specified by
POSIX, which makes it
non-portable. This isn’t such a big deal, except that different sed
s require
different arguments! GNU sed
edits in place, no argument provided. BSD sed
,
such as the one on macOS, requires a suffix:
file.suffix
and
the new contents in file
;So now, every sed -i
solution to a problem needs to at least
I don’t know about you, but I wonder if the solution to editing files in place
is a lot simpler…
sed
for streams, ed
for filessed
stands for “stream editor.” It was designed based on the text-editor
ed
’s commands! ed
is built to edit files.
ed
(or the improved
POSIX-specified ex
);sed
is an option.I cannot emphasize this enough. Trying to use sed -i
in any kind of portable
anything is likely to break; worse was the thought that sed
should ever be
used for editing files! Use a text-editor: if you thought “I’m automating, I
don’t want to run a text-editor to automate,” well, remember:
ed
and ex
, anded
takes commands on standard in. It can be made silent with -s
, and the
argument is a file to edit. I ignore -p
for now because it isn’t useful for
scripting/automation. So, to script ed
, generate a list of commands and pipe
it in!
printf '%s\n' g/abc/d w q | ed -s file
That’s the most portable, but bash
users can probably do
ed -s file <<EOF
g/abc/d
w
q
EOF
There is quite a bit of flexibility here; the left-hand side could actually be
another program that generates ed
commands on standard out! It turns out,
this is what diff
does: in its default output mode, we have
These lines resemble
ed
subcommands to convertfile1
intofile2
. The line numbers before the action letters shall pertain tofile1
; those after shall pertain tofile2
. Thus, by exchanginga
ford
and reading the line in reverse order, one can also determine how to convertfile2
intofile1
. As ined
, identical pairs (wherenum1=num2
) are abbreviated as a single number.
And when we ask for the -e
output mode:
With the
-e
option, a script shall be produced that shall, when provided as input toed
, along with an appendedw
(write) command, convertfile1
intofile2
.
So now, you can probably write a patch
command you parse the output
from
diff
, with maybe slight modification, and then pass it as input to ed
!