Transferred from: https://www.cnblogs.com/cocowool/p/6409643.html
This article mainly records the learning situation of two commands: diff and Patch. Diff and Patch are a pair of tools that use this tool to get the difference between an update file and a history file and apply the update to the history file. In mathematics, diff is the difference between two sets, and patch is the operation of two sets.
A simple example
Use this example to illustrate how to compare and patch files.
There are two files in Original.txt and Updated.txt, as follows:
#include <stdio.h> function old () {printf ( "This is a file\n return 0;}
#include stdio.hfunction new(){ printf("This is b file\n"); return 0;}
diff original.txt updated.txt
The result of the execution is
Here are some explanations for some of the symbols appearing in the results. 1,4c1
, the content output is actually given to patches, indicating that the 1 to 4 lines in the Original.txt file should be replaced by the contents of the Updated.txt, replacing the 1th line of Updated.txt. There may be three letters that indicate a different meaning, namely C for update, a for append, and D for delete.
c indicates that the contents of the M,n line in the original file will be replaced by the contents of the updated file.
A means append, at which point the left number can only be a number, not a range, which indicates that the right digit is appended to the original file.
D means delete. The number on the left may be a range that represents the content to be deleted, and the right side is a number that indicates where the updated file should appear if it is not deleted. Some people may think that the number behind is superfluous, keep this number because the patch can be used in reverse.
<
Indicates that the patch should remove the contents of the flag behind it.
>
Indicates that patches should add the content that follows this flag.
Knowing the output of diff, it is time to create a patch for the original file. The patch is actually the output of the diff, and we can either save the output directly to a file or use the pipe symbol to do it, as follows:
diff original.txt updated.txt > mypatch.patch
Then we have a patch file to update the original file with the updated file.
patch original.txt -i my patch.patch -o updated-1.txt
This command will generate a new file that can be seen exactly as it was before our UPDATE.TXTW file.
Context Patches
Look at the result style before the diff, for the location that needs to be replaced, just give the line number, if the file suddenly added a blank line, the patch applied when the problem occurs. In another case, if the patch file is applied to an incorrect source file, the patch can be applied successfully if the file has exactly the same number of rows. And that's the result we don't want to see. Fortunately, diff provides a different result style to avoid these problems.
diff -c original.txt updated.txt
The comparison result contains the file name, so that when we apply the patch, we do not have to enter the file name, thus saving time and avoid the possibility of file name input error. The file name is followed by the modified time of the files. And then down is 15 asterisks * indicates that the following content is file replacement, update, delete, and so on. *
and -
the included number or number range represents the line number, and the !
start content represents what needs to be replaced, represents what needs to be -
deleted, +
represents what needs to be added, and patches updates the file based on the context relationship.
patch -i mypatch2.patch -o updated.txt
Note that if you do not specify an output file, the source file will be updated (this is what the patch file does). Often we apply patches to the source file, often requiring processing of multiple files.
Compare multiple files and apply patches
The simplest way to compare multiple files is to follow the folder directly behind the command, for example, if you include subfolders, remember to add the-r parameter.
diff originaldirectory updateddirectory
You can also look at the results of context comparisons
Rousseaudemacbook-pro:diff rousseau$ diff-c Original updateDiff-c Original/function.txt Update/function.txtOriginal/function.txt Fri Feb 17 09:41:26 2017---update/function.txt Fri Feb 17 09:42:06 2017***************1,5 ****!#includ <stdio.h>function Main (){Return 1;}---1,8----!#include <stdio.h>!#include <stdlib.h>function Main (){+printf"This is function main\n");+Return 1;}Diff-c Original/original.txt Update/original.txtOriginal/original.txt Fri Feb 17 09:40:29 2017---update/original.txt Fri Feb 17 09:40:51 2017***************1,9 * * *#include <stdio.h>!function old () {! printf ( "This is a file\n" ); return 0}-void 0; #include <stdio.h>! function newd () {! printf ( "This is a new file \ n "); return 0 /span>
Here to see how to apply patches to multiple files, first generate a patch file, we still use the context format.diff -c original update > directory.patch
Copy the original folder and patch file in a new directory, and patch -i directory.patch
you will be prompted not to find the file, because patch will find the file in the current folder (by default, Patch will remove all folders before the file name) because the patch file is outside the folder, So we should tell patch not to do this, use -p
parameters.
patch -p0 -i directory.patch
Some people may ask, if I move the patch file to the folder to patch the operation is not possible, please do not do so. If there are subfolders in the folder, patches do not look for files in subfolders, which can affect the results, especially when there are files of the same name in different folders.
Operations to restore patch files
Sometimes the version needs to be withdrawn, at which point the-R parameter can be used.
patch -p0 -R -i directory.patch
Unified Format
GNU diff and Patch also provides a format called the Unifiedformat. This format is more streamlined, similar to the context format. But instead of separating the source files from the update files, they are grouped together. And there are no special replacement flags, only - and +.
diff -u original update
Written in the last
Early backup is a good practice when you patch a text file, which prevents you from worrying about a bunch of unrecoverable files in the wrong situation.
Resources:
1. Using Diff and patch
2. diff Compare two folders
3. GNU Diff and patch
Diff and Patch in Linux