On Linux, we sometimes want to apply a patch to a file. Even without using git or similar tools, we can easily get it done with the built-in Linux utilities.

First, let’s assume the file we want looks like this:

5.
4.
3.
2.
1.
0.

Now we have a file like this:

5.
8.
4.
2.
0.

Because the file is very regular, we can generate one programmatically:

Bash
$ i=5; while [ $i -ge 0 ]; do echo $i;i=$(($i-1));done | xargs -n 1 -I{}  sh -c 'echo {}.'
5.
4.
3.
2.
1.
0.

We can see with the naked eye that the two are different. Let’s generate a diff to inspect:

Bash
$ i=5; while [ $i -ge 0 ]; do echo $i;i=$(($i-1));done | xargs -n 1 -I{}  sh -c 'echo {}.' | diff orig.txt -
2d1
< 8.
3a3
> 3.
4a5
> 1.

diff takes two parameters after it; you can use forms such as

Bash
diff FILE-OLD FILE-NEW
diff DIR-OLD DIR-NEW

and so on. If FILE* or DIR* is -, that slot means stdin. You can use --help to view more details.

Then we can output a diff file.

As in the previous command, its *-OLD is orig.txt, *-NEW is stdin, and because of the pipeline, it is essentially the stdout of the previous sh.

We can inspect the diff content: roughly speaking, to transform the left side into the right side, we need to remove the second line 8. and add 3. and 1..

We can redirect this stdout into a patch file:

Bash
$ i=5; while [ $i -ge 0 ]; do echo $i;i=$(($i-1));done | xargs -n 1 -I{}  sh -c 'echo {}.' | diff orig.txt - > orig.txt.patch

Now we have orig.txt and orig.txt.patch. How do we update orig.txt? Another command, patch, is also straightforward.

Bash
$ patch orig.txt orig.txt.patch
patching file orig.txt

Then check the result:

Bash
$ cat orig.txt
5.
4.
3.
2.
1.
0.