2

I'm aware that diff -e can output an ed script. And my understanding is that ed and sed share their approach, but that ed is interactive, and sed is for streams.

What I would like to do is take the output of diff -e (or some other invocation of diff) and munge it into an invocation of sed such that invoking that command with the original "before" file as input produces output equivalent to the "after" file from the diff invocation. I would like to format the command as a collection of -e <BLERG> options passed to sed to avoid having to write the ed/sed script to another file.

I've tried a bunch of obvious mungings, but I'm not getting the desired (or even reasonable looking) output, and I think I'm missing some overarching thing. Is this possible?

3
  • Does it have to be sed?
    – Paul
    Mar 29, 2014 at 12:28
  • I suppose no, it doesn't have to be.
    – ipmcc
    Mar 29, 2014 at 15:05
  • But I do want to use it in a streaming context, like: curl -s http://someurl.com | [Command I'm looking for] > outputFile so sed seems like the natural choice.
    – ipmcc
    Mar 29, 2014 at 15:18

2 Answers 2

6

You could stick with ed: assuming you wanted to diff file1 and file2, and then apply the changes to file1 and write to a file named file1.b:

{ diff -e file1 file2; echo "w file1.b"; echo q; } | ed file1

Now, there should be no difference between file2 and file1.b:

$ diff file2 file1.b && echo "no diff"
no diff
2
  • I think you're on the right track, but the problem with this solution is that it presupposes the existence of file2. The situation I'm in is that file1 is always available. I make file2 by doing some hand-editing to file1, but file2 is periodically deleted out from under me, so the object is to create a command pipeline such that I can cat file1 | [Command I'm looking for] > file2 to recreate file2 at will.
    – ipmcc
    Mar 29, 2014 at 15:10
  • @ipmcc - you don't need file2; if you have the script use cat script instead of diff... or embed your script in a heredoc and pass it to ed -s file1<<... but really, your question doesn't make sense. The algorithm used by diff -e is really dumb. If you have to replace ten occurrences of "foo" that span over 40 lines with "bar" it will delete a block of 40 lines and append a new block of 40 lines instead of doing a simple 15,55s/foo/bar/g. And if you tried to make it work with sed you'd spend more time to convert it (because ed operates backwards) than write your own. Apr 3, 2015 at 18:08
2

The diff and the subsequent application of the diff differences are at different times. So assuming you have the output from your diff, I would use patch:

diff -u original.html new.html > original.patch

Then on the receiving end:

curl -s http://someurl.com > original.html; patch < original.patch

This does mean engineering your filenames to be the same though, as they are contained in the patch file.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .