Episode: 4657 Title: UNIX Curio #8 - Comparing Files Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr4657/hpr4657.mp3 Transcribed: 2026-07-31 16:16:06 (official HPR transcript) --- This is Hacker Public Radio Episode 4657, for 2026-06-09 Today's show is entitled, "UNIX Curio #8 - Comparing Files" The host is Vance and the duration is 00:14:20 The flag is Clean, and the license is CC-BY-SA The summary is "Finding out what's the diff, without using "diff"" Hi there, I'm Vance and welcome to Unix Curio number 8. This series is dedicated to exploring little-known and occasionally useful, trinkets lurking in the dusty corners of Unix-like operating systems. Before getting into today's topic, let me start with an apology and corrections to previous episodes. In a recent conversation, a friend pointed out to me that the historical BSD versions were not necessarily developed in numerical order. Instead, the 2.x BSD versions were created to run on the PDP-11 while 3 BSD and 4.x BSD ran on the Vax, at least until support was added to 4.x for other processors. For a while, they were developed alongside each other. So 2.9 BSD actually appeared after 4.2 BSD. In addition, the net 2 release came after 4.3 BSD, but before 2.11 BSD. Probably others like me have fallen into the trap of assuming larger version numbers came later, but I should have paid closer attention to dates while researching. In Unix-Curio 3, I implied that the base name utility first appeared in BSD as part of version 2.9 in 1983. While it actually was in 3 BSD from 1979, shortly after Bell Laboratories 7th edition was in the net 2 release from 1991, not 4.4 BSD in 1993. In Unix-Curio 7, about compression, I got the date right for the compact utility. It was first developed for BSD in 1979. However, the link in the show notes points to the source code file in 2.9 BSD when the program appeared first in 3 BSD. I will try to be more careful in the future about identifying where and when certain commands originated. Sorry again if you were misled. Getting back to today's episode, it came about when I was clearing out some open browser tabs and stumbled upon a topic I had forgotten investigating. Most users of Unix-Light systems are probably familiar with the diff utility. It is widely used with source code to compare two files and see what the differences are between them. Non-programmers, like me, also use it to examine what has changed in different versions of scripts or configuration files. Quite a few pieces of newer software can compare different versions of data and express changes in a format either identical to or similar to diff output. However, there are two other long-standing tools for this purpose that are far less known and deserve in my view to be termed Unix-Curios. The first of these is CMP in the phonetic alphabet spelled Charlie Mike Papa. While diff is primarily intended to be used on text files and compares them line by line, CMP compares files byte by byte. In my experience, its main use is to see whether two binary files are in fact identical. If they are, CMP outputs nothing and returns an exit status of zero. Back when methods of transferring files were not as reliable as they are today, this was the tool I would reach for sometimes. For example, you could use it to confirm that the data on a CD-ROM you burned was the same as the original. If there is a difference between the files, CMP will return an exit status of one. By default, it will also print the location, the byte and line number of the first differing byte. When used with the hyphen L option, that's Lima in the phonetic alphabet, it will print the location and value of every byte that differs. There is one exception to these. If the files are the same, except that one is shorter than the other, it will print on message to that effect. The exit status will still be one in that case. Using the hyphen S option, that's Sierra in the phonetic alphabet, with CMP, will cause it to be totally silent and output nothing. The exit status will indicate whether the files are the same, different, or if the exit status is greater than one, that an error occurred. This makes it useful for scripting. For example, in case you wanted to confirm, that a file copied to another location arrived fully intact. It is worth noting that diff is also capable of comparing binary files. However, it is not required by posics to report what is actually different or where the difference is occur. The same exit status as in CMP is returned. Zero if the files are the same, one if they are different, or greater than one if an error occurred. While many implementations offer an option to suppress the output, this is not in the standard. The most portable method would be to instead redirect output to slash dev slash null. On my system, the diff utility is three times the size of CMP, so if you don't need its extra capabilities, it is a less efficient way of doing the job. The other Unix Curio for today is calm, spelled COMM, or in the phonetic alphabet, Charlie Oscar Mike Mike, and this utility is also intended to compare two files. This time to see what is common between them. Ben Fallen briefly talked about it a few years ago in hacker public radio episode 3889. Compared to the others, it has a much more specific use case. The two files are expected to be text files that are already sorted. What COM will do is print a tab separated list of all the lines appearing in either or both files. Lines only in the first file will appear in the first column. Lines only in the second file will be in the second column, and lines in both files will be in the third column. Any combination of the options, hyphen 1, hyphen 2, and hyphen 3 can be used with COM to suppress printing of the first, second, or third column respectively. By the way, these options are the numerals, one, two, and three. Using all three options at the same time is supported, but it results in no output, so that isn't very useful. Unlike the other utilities, the exit status of COM doesn't tell you anything about the two files. It will be zero if the program ran successfully, and greater than zero if it didn't. I'm not sure if I have ever actually used COM for anything practical. I find it's default output to be a bit difficult to meaningfully interpret, plus you need to ensure the two files are already sorted. It seems to be best suited to comparing lists, and one use case that Kenfall and mentioned would be comparing two lists of files to see if any are missing. The command COM, hyphen 3, list A, list B, would print files that only appear in list A in the first column, and those only in list B in the second column. This would let you ignore all the file names that appear in both, and focus on those that were absent from one or the other. If, on the other hand, you only wanted to see the file names that are on both lists, COM, hyphen 1, 2, list A, list B, would give you that. Some more frivolous potential uses also come to mind. If for some reason the cat utility is broken on your system, you could use COM, list A, slash dev, slash null, to print the file list A instead. If you want to insert tab characters before every line of a file, but have an a version to using said or all, then COM, slash dev, slash null, list A would output list A with one tab before each line, and COM, list A, list A would insert two tabs. A bit silly, but it would work. The GNU implementation of COM even lets you choose something other than a tab to separate the columns, so you could go wild with that. According to the POSIX specifications for CMP and COM, one of the two file names given as arguments, but not both can be a hyphen. In which case, standard input will be used for that, quote, file, unquote, in the comparison. So the results are undefined, if both arguments are the same, phyphospecial, character special, or block special file. Some implementations might not have these limitations, but you shouldn't rely on that everywhere. All three of these were developed quite early. The CMP utility appeared in 1971's first edition Unix, while COM and Diff seemed to have made their debut in fourth edition Unix from 1973. I'm not 100% sure about that. Diff might have come a little bit later, but still in the early 1970's. The original versions might not have behaved exactly like their modern counterparts, and newer implementations, especially of the Diff utility, have acquired additional options and capabilities, but the basic operation of each has stayed the same. The next time you need to compare files against each other, consider whether CMP or COM might be appropriate before automatically reaching for Diff. They all have their uses in different situations. Thanks for listening. I haven't yet written the next Unix Curio, but there are a couple topics I'm working on. Keep an eye out here on Hacker Public Radio for them to appear. If you have an idea for a topic, or want to ask a question, please comment on this episode on the HPR website. You have been listening to the Hacker Public Radio podcast, at hackerpublicradio.org. Today's show was contributed by a HPR listener like yourself. If you ever thought of recording a podcast, then visit the HPR site to find out how easy it really is. Hosting for HPR has been kindly provided by anhonesthost.com, the Internet Archive, rsync.net, and the HPR Community Content Delivery Network. Unless otherwise stated, today's show is released under a Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.