2

File A

Apples
Bananas
Clementines
Dates

File B

Apples
Blueberries
Cherries
Dates

I want to diff A and B to generate a patch that when applied to C will change the line Clementines > Cherries but will ignore the second line (Blueberries/Blackcurrants/whatever).

File C (before patch)

Apples
Blackcurrants
Clementines
Dates

File C (after patch)

Apples
Blackcurrants
Cherries
Dates

Ideally I would like a patch with context, as this sequence is not guaranteed to always appear in the same place in the file. In my mind the context would contain some form of wildcard line after Apples and before Clementines.

I am open to manually editing the diff output if necessary, but if there's a repeatable command for creating a context-based diff with a wildcard in place of a specific regex match that would be great.

I would like to be able to send this patch to a friend who has file C and have them run a patch command without having to manually edit anything on their end.

How can this be done?

1
  • Your example doesn't make clear what's the criteria for the replacement. It could be replace the word "Clementines" with "Cherries" or ... the line "Clementines" ... either with or without context, e.g. *between "Apples" and "Dates". Do you need a single replacement only or multiple replacements of the same word/line or of different patterns. Do you need a mechanism to automatically create a patch/script from files A and B or can you do this manually, maybe based on some diff output. Is there a relation between the line numbers in A, B and C? Please edit your question to clarify this.
    – Bodo
    May 6, 2021 at 10:52

2 Answers 2

1

Assuming that you’re using GNU diff, there’s no way to get it to generate the exact patch you’re after. It is possible to ask diff to ignore lines matching a given regex, with the -I option, but it will only ignore entire hunks consisting of only such changes. In this case, any hunk (even with no context) will change both the “Bananas” and “Clementines” lines.

One possibility that doesn’t involve fancy patch editing is to ask diff to generate an ed script:

diff -e

This will produce

2,3c
Blueberries
Cherries
.

which can be adapted to produce the patch you’re after:

3,3c
Cherries
.
0

If you do patch(1), pieces that don't fit get saved in a reject file. You can then go over that one and apply (or not) the hunks that didn't get in.

Another possibility (for hardcore jocks) is to just edit the patch. Note that the diff(1) format is designed for readability, not for editing. You have to be careful not to mess up the line numbers or other markers.

If you want to create a patch for shipping around, perhaps the simplest path is to just apply the patch as is, edit the resulting file to taste, and then redo the patch against the edited file.

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.