Sorting by IP Addresses 2

Yesterday, I told you about my difficulties in trying to sort an Org mode table. I came up with a solution that was, um, less than optimal but at least I got the table sorted. It bugged me that Org mode couldn’t sort by IP address so I wrote a patch to add a “sort by IP address” option to org-table-sort-lines and submitted it.

Nicolas Goaziou pushed me to make a more general patch that would allow a user to specify any sorting method. The idea was to duplicate the ?f ?F functionality of org-sort-list. After some back and forth, the patch was accepted and is now on the master branch. If you’re tracking the Org repository, it’s available now. If you’re getting Org from ELPA or just updating with major releases it should be along shortly.

Org mode still doesn’t have an IP sort option but now I can write my own. First, I need a comparison function:

(defun jcs-ip-lessp (ip1 ip2 &optional op)
  "Compare two IP addresses.
Unless the optional argument OP is provided, this function will return T
if IP1 is less than IP2 or NIL otherwise. The optional argument OP is
intended to be #'> to support reverse sorting."
  (setq cmp (or op #'<))
  (cl-labels ((compare (l1 l2)
                       (if (or (null l1) (null l2))
                           nil
                         (let ((n1 (string-to-number (car l1)))
                               (n2 (string-to-number (car l2))))
                           (cond
                            ((funcall cmp n1 n2) t)
                            ((= n1 n2) (compare (cdr l1) (cdr l2)))
                            (t nil))))))
    (compare (split-string ip1 "\\.") (split-string ip2 "\\."))))

The rest is easy. I just need to call org-table-sort-lines with jcs-ip-lessp and the appropriate key extraction function:

(defun jcs-ip-sort ()
  (interactive)
  (org-table-sort-lines nil ?f #'org-sort-remove-invisible #'jcs-ip-lessp))

(defun jcs-ip-sort-reverse ()
  (interactive)
  (org-table-sort-lines nil ?F #'org-sort-remove-invisible
                        (lambda (ip1 ip2) (jcs-ip-lessp ip1 ip2 #'>))))

I just add this to my init.el and then call jcs-ip-sort or jcs-ip-sort-reverse to sort a table by IP address.

You can also specify the key extraction function interactively and org-table-sort-lines will choose either a string or numeric sort depending on the type of the first extracted key.

This entry was posted in General and tagged , . Bookmark the permalink.