Combine multiple aerc-style address books into a single, unified address book. The unified address book contains no duplicate email addresses, and the addresses are sorted based on the order of the books, the order of the addresses within the books, and the optional ranks assigned to addresses.

Using it in aerc

With addr-book-combine, I can simultaneously use my contacts (stored in khard) and the results of maildir-rank-addr for auto-completion in the aerc email client. Here’s a snippet from my aerc config:

address-book-cmd = addr-book-combine \
                       -c "khard email --remove-first-line --parsable '%s'" \
                       -c "rg -F -i -- '%s' ~/.ranked-addrs.tsv"

.ranked-addrs.tsv contains the output of maildir-rank-addr, which I configured to print the actual rank of the addresses with the following template:

template = "{{.Address}}\t{{.Name}}\t{{.TotalRank}}"

How sorting works

When comparing two addresses, the following procedure is applied:

  1. First, if the addresses are not from the same book, the address from the earlier book appears first.
  2. Next, each book is checked to compare the addresses:
    • If neither address is ranked within the book, check in the next book.
    • If only one address is ranked within the book, the ranked address appears first.
    • If both addresses have the same rank, check in the next book.
    • If the addresses have different ranks, the address with the lowest rank appears first.
  3. Finally, if no address has been chosen to appear first, preserve the original order of the addresses.

Check out the test code to see some examples.

Example input/output

Here’s an example of addr-book-combine in action:

$ cat book1.tsv
a@example.com	Andy Apple	1
b@example.com	Bart Berry
c@example.com	Chad Cherry	5
d@example.com	Dale Donut

$ cat book2.tsv
d@example.com	D. Donut	4
a@example.com	Andy Apple	2
e@example.com	Eric Egg
f@example.com	Fred Fig

$ addr-book-combine -f book1.tsv -f book2.tsv
a@example.com	Andy Apple	0
c@example.com	Chad Cherry	1
d@example.com	Dale Donut	2
b@example.com	Bart Berry	3
e@example.com	Eric Egg	4
f@example.com	Fred Fig	4