Compare Two Files (with Emacs)

Because of a change in a system’s design, today I needed to compare two long lists, find what was new and output the results. As most daily problems, there is already plenty of tools that almost do what you want.

The two said list where in fact lists of components’ IDs, each on a separate line. Because those files were .txt, instead of evil .doc, I had a world of possibilities to solve my problem. Evidently, because I spend most of my days in Emacs, I used it!

First things first: I couldn’t use M-x diff for various reasons. Most notably, I had no way of knowing if the order was preserved between the two files. In addition, those were long lists; I didn’t want to check all of them in the diff buffer. Finally, I only cared for what was new, deleted stuff was irrelevant.

It took me around 10 minutes to hack this little function. Doing the comparison by hand would have been at least in the hour magnitude and would have been highly susceptible to human mistakes.

(defun new-stuff (old-file new-file)
  "Compare the OLD-FILE with the NEW-FILE and output 
new lines in \"*new-stuff*\" buffer."
(with-temp-buffer 
  (insert-file-contents new-file)
  (let ((lines (split-string
                (buffer-string) "\n" t))
        (new-stuff nil))
    (with-temp-buffer
      (insert-file-contents old-file)
      (mapc '(lambda (arg)
               (goto-char (point-min))
               (unless (re-search-forward 
                        (regexp-quote arg) 
                        nil t nil)
                 (push arg new-stuff))) 
            lines))
    (switch-to-buffer "*new-stuff*")
    (erase-buffer)
    (mapc '(lambda(arg) 
             (insert arg) 
             (newline)) 
          new-stuff))))

What’s interesting about this function is the number of Emacs’ aspects it touches. You have to manipulate buffers, files and strings. You also have to understand how a list is made by using the split-string function and how mapping works, so that each of the spitted string is compared with the old file. Behold, there is also the famous lambda anonymous function!

Writing a function you will use every day for the next decade feels really good. However, writing a one-use-only function is also greatly rewarding! No need to optimize, no fuss about being “clear” enough. Hack, see if it works, enjoy the time saved.

Lisp is beautiful. Lisp is fun.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: