comm command
To compare two file and find the common content:
comm file_1 file_2
The result will show:
• The first column shows unique lines in file_1
• The second column shows unique lines in file_2
• The last column shows the content common in both the files
Compare file and patch file with diff
Compare
In real life, we often need to update a configuration file or something else. It’s convenience to create a patch file and distributed to all other computers, then patch them by command or even by script.
You could, for example, write a few words in a normal text file, make some modifications, and then save the modified content to a second file. Then, you could compare these files with diff, like this:
I will use the file original file with the content “These are a few words.” , the file updatedfile with the content “These still are just a few words.” and the file updatedfile2 with empty content.
[root@localhost ~]$ diff originalfile updatedfile
1c1
< These are a few words.
No newline at end of file
—
> These still are just a few words.
No newline at end of file
Then we can compare original file and updatedfile2:
[root@localhost:~]# diff original updatedfile2
1d0
<These are a few words.
\ No newline at end of file
The 1c1 is a way of indicating line numbers and specifying what should be done. Note that those line numbers can also be line ranges (12,15 means line 12 to line 15).
The “c” tells patch to replace the content of the lines. Two other characters with a meaning exist: “a” and “d”, with “a” meaning “add” or “append” and “d” meaning “delete”.
syntax:
(line number or range)(c, a or d)(line number or range)
when using “a” or “d”, one of the (line number or range) parts may only contain a single line number.
- When using “c”, the line numbers left of it are the lines in the original file that should be replaced with text contained in the patch, and the line numbers right of it are the lines the content should be in in the patched version of the file.
- When using “a”, the line number on the left may only be a single number, meaning where to add the lines in the patched version of the file, and the line numbers right of it are the lines the content should be in in the patched version of the file.
- When using “d”, the line numbers left of it are the lines that should be deleted to create the patched version of the file, and the line number on the right may only be a single number, telling where the lines would have been in the patched version of the file if they wouldn’t have been deleted. You might think that that last number is redundant, but remember that patches can also be applied in a reverse way. I’ll explain more about that later on in this tutorial.
The “<” means that patch should remove the characters after this sign, and the “>” means that the characters after this sign should be added. When replacing content (a “c” between the line numbers), you will see both the < and the > sign. When adding content (an “a” between the line numbers), you’ll only see the > sign, and when deleting content (a “d” between the line numbers), only the < sign.
Create a patch
If we want to create a patch, we should put the output of diff into a file. We can let bash write diff’s output to a file for us this way:
[root@localhost ~]$ diff originalfile updatedfile > patchfile.patch
We distribute the patchfile to all other user, and they can use the patchfile to change a copy of originalfile to a copy of updatedfile:
[root@localhost ~]$ patch originalfile -i patchfile.patch -o updatedfile
Contextual patching
In the first chapter, we created a patch using diff’s normal format. This format, however, doesn’t provide any of the lines of context around the ones to be replaced, and therefore, a change in the line numbers (one or more extra newlines somewhere, or some deleted lines) would make it very difficult for the patch program to determine which lines to change instead. Also, if a different file that is being patched by accident contains the same lines as the original file at the right places, patch will happily apply the patchfile’s changes to this file. This could result in broken code and other unwanted side-effects. Fortunately, diff supports other formats than the normal one. Let’s create a patch for the same files, but this time using the context output format:
[rechosen@localhost ~]$ diff -c originalfile updatedfile
By now, it should be clear that you should replace the filenames where necessary =). You should get an output like this:
*** originalfile 2007-02-03 22:15:48.000000000 0100
— updatedfile 2007-02-03 22:15:56.000000000 0100
***************
*** 1 ****
! These are a few words.
— 1 —-
! These still are just a few words.
As you can see, the filenames are included. This will save us some typing when applying the patch. The timestamps you can see next to the filenames are the date and time of the last modification of the file. The line with 15 *’s indicates the starting of a hunk. A hunk describes which changes, like replacements, additions and deletions, should be made to a certain block of text. The two numbers 1 are line numbers (again, these can also be line ranges (12,15 means line 12 to line 15)), and ! means that the line should be replaced. The line with a ! before the three -‘s (hey, where did we see those before?) should be replaced by the second line with a !, after the three -‘s (of course, the ! itself will not be included; it’s context format syntax).
As you can see, there aren’t any c’s, a’s and d’s here. The action to perform is determined by the character in front of the line. The !, as explained, means that the line should be replaced. The other available characters are +, – and ” ” (a space). The + means add (or append), the – means delete, and the ” ” means nothing: patch will only use it as context to be sure it’s modifying the right part of the file.
Applying this patch is a bit easier: under the same circumstances as before (let bash write the diff output to a file again, then copy the patchfile and the original file to an other location), you’ll need to run:
[root@localhost ~]$ patch -i patchfile.patch -o updatedfile
Reference
https://linuxacademy.com/blog/linux/introduction-using-diff-and-patch/