1

I'm using diff and patch to patch some files. In my situation, I am not permitted to distribute any of the original file.

Right now, the diffs look something like this:

1c1
< Hello, this is the original.
---
> Hey, this is the new version.

I don't want to (and for reasons can't) include the original lines. Is it possible to make a diff that doesn't include the original lines, just what replaces the original lines?

The closest I've found is using diff -e to generate an ed script, but it doesn't look like ed is installed by default on Debian. Is it possible to do this with diff and patch?

EDIT: For example, I want to take a file that looks like this:

Hello, this is a file.
It is pretty cool.
I wrote it in a text editor.

to a file like this:

Hello, this is a file.
It is kinda awesome.
I wrote it in a text editor.

A regular diff would include the original line, and look like this:

2c2
< It is pretty cool.
---
> It is kinda awesome.

I don't want the original line ("It is pretty cool.") to even be in the diff file. I'd like a diff file that basically says replace line 2 with: It is kinda awesomewhich has all the needed info to patch, but includes none of the original content. Essentially, I want a diff that says "replace whatever is on line 2 with this:".

Running patch -e to make an ed script generates all that I need, but I don't want to use that as ed isn't included in Debian by default.

2c
It is kinda awesome.
.
  • 2
    No ed?!?!? ed is the standard text editor! – Jeff Schaller Feb 4 '16 at 23:18
  • I was kind of surprised too, as it's part of POSIX, so it should be in Debian. – IBPX Feb 4 '16 at 23:19
  • Maybe I don't understand your situation, but what about just providing the new file with instructions to copy it over the existing file? – Jeff Schaller Feb 5 '16 at 0:33
  • Let me clarify: In my situation, I am not permitted to redistribute any of the original content, so I can't include it in the patch. – IBPX Feb 5 '16 at 0:38
  • Off the top of my head, I'm imagining a big of sed for each file (sed 2s/.*/new text/; 5s/.*/other text/ ...). If you can't rely on -i being there for sed, you're also looking at working with temp files – Jeff Schaller Feb 5 '16 at 1:04
2

To capture what I understand from the Q's comments, I'm going to answer that "no, it is not possible to do what you want with diff and patch", since they must include context, which includes content that you can't distribute.

Given that you can't rely on ed to be present, if you can rely on sed to be there, then you could loop through your changed files and update each one with a sed expression:

$ cp input tempfile && \
$ sed \
    -e '2s/.*/It is kinda awesome./' \
    -e '4s/.*/No really, this is line 4/' \
  tempfile > input && \
$ rm tempfile

I broke the commands up to hint at the possibility of a script-writing script that would generate the above commands, replacing "input" with the filename that needs to be changed and the "-e ..." lines with the content that needs to change. Here I'm changing whatever's on line 2 and line 4 with the corresponding text.

If you're concerned about "tempfile" colliding with an existing name, see if this spartan system has mktemp. You could save some mktemp cycles by creating one temp file to (re)use for each input file.

If this ed-less system has a sed that supports the -i flag, then you can simplify that batch to:

$ sed -i.orig \
    -e '2s/.*/It is kinda awesome./' \
    -e '4s/.*/No really, this is line 4/' \
  input

mikeserv brings up a good point with sed's 'c' command; GNU sed appears to accept the replacement text on the same line as the 'c' command, but just in case yours doesn't, here's one option:

$ cat > patch.sed
2c\
this is the new line two
4c\
this is an awesomer line four
^D
$ sed -f patch.sed input > output ## or sed -i.orig -f patch.sed input
  • 1
    @mikeserv, I had trouble using c\ on the same line as the replacement text; see chatroom if you're still there. I like the 'c' idea; will rework the answer a bit – Jeff Schaller Feb 5 '16 at 3:02
  • thats possible - its really not the correct way to do it, but i figured with the -i and the specified Debian environment i might get away w/ modifying your (very good) answer as little as possible while hopefully still marginally improving it and so omitted the correct newlines there. (though you should remove the -i in my opinion...). I like your edit better. Options are good. – mikeserv Feb 5 '16 at 3:04
  • thanks, mike; I updated the answer. tmtowtdi! it's a good day when I can solve a problem and learn something! – Jeff Schaller Feb 5 '16 at 3:06
  • Btw, @ibpx, be sure to escape / or ' characters in any replacement text, depending on the method you choose. – Jeff Schaller Feb 5 '16 at 3:23
  • 1
    There's more than one way to do it -- sorry, must be a perl-ism – Jeff Schaller Feb 5 '16 at 3:32
-1
diff file1  file2  | grep ^">"

comes to mind

  • I mean produce a file that can be applied over the original, without containing any of the original. That command just shows me what has changed, not even where it has been changed. – IBPX Feb 4 '16 at 23:17
  • can you update your question with a few of sample file contents ? I mean, provide dummy files' content to run diff on and the output you are trying to obtain as a result of this command – MelBurslan Feb 4 '16 at 23:20
  • I updated the question. – IBPX Feb 4 '16 at 23:28
-1

At least with GNU diff, it seems to be possible with suitable LFMT (line format) specifiers:

diff --new-line-format="replace line %-dn with:%c'\012'%L" --unchanged-line-format= --old-line-format= file1 file2

Tested with:

$ cat file1
Hello, this is a file.
It is pretty cool.
I wrote it in a text editor.

$ cat file2
Hello, this is a file.
It is kinda awesome.
I wrote it in a text editor.

$ diff --new-line-format="replace line %-dn with:%c'\012'%L" --unchanged-line-format= --old-line-format= file1 file2 
replace line 2 with: 
It is kinda awesome.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.