January will mark the 20th year I have maintained the list of books that I read each year. I started my list back in January 1, 1996, when notions of self-tracking in the digital age hadn’t yet risen to their current ubiquitous levels. Over those two decades, I have read 590 books (I’m in the middle of my 591st as I write this) and my list has been maintained in (so it seems) nearly as many formats.
In the early days, I kept my list in a Microsoft Access database. I did this because it seemed to me to the be most efficient way to store the data, and I was very big into efficiency back in those days. Eventually, this format was migrated into MySQL. But I found over time that the queries I would make against the data were not nearly as sophisticated as those I imagined I would make. Modeling the data and maintaining it took more time than it was worth.
Eventually, the list moved into a page in this WordPress blog. And for many years, that page was manually maintained. About a year ago, I took the final step at simplifying my list, making it into a simple, plain-text file stored on Dropbox, and writing a simple plug-in for WordPress to read and render the text file as a web page.
This is an example I think is pretty typical: design starts out overly complex because the practical use cases are difficult to imagine. Over time, the design is simplified to focus on just those use cases that are important and meaningful. While my reading list started out as a highly normalized database, today it is a simple text file, and I can do more with it in less time than I’ve ever been able to do before. Today, I can ask all sorts of questions about my reading list simply by knowing a few basic commands at the command line.
My reading list as a text file
I use Sublime Text as my default text editor in both Windows and Mac, and Sublime Text has a few features that help simplify the maintenance of my list. The biggest win is that I don’t need to record the number for each book the way I used to. I simply add a new line to the file with the title and when I look at that title in Sublime Text, I can easily see what number that book is (in the order for which I’ve read it). For instance, I can see that Revival by Stephen King is the 589th book I have read since January 1, 1996.
What I track about my reading
I used to capture all kinds of information about what I read, but I found that I almost never used it. I used to categorize and classify the books, and break them into fiction and nonfiction, and the gender of the author. But I never used it. So I simplified things in the text file. Today, I capture just a few pieces of information:
- Date completed
I have a few symbols I use after the title which indicate information useful to me:
- * = a book I really liked, and would recommend.
- @ = audiobook
- + = e-book
- ^ = a repeated reading (that is, I have read the book more than once).
This turns out to be enough information, and to satisfy most of the questions I have about my reading list and reading habits.
Querying my reading list
One “secret” of my productivity is that I am a big command-line junkie. I have been since I first started playing around with Linux in the mid-1990s. I realize that not everyone uses the command line, and not everyone is comfortable with it, but for many things, I am much faster at the command line than with an app and a mouse.
I always have at least one command window open, whether on a Mac, or Windows (where I use Cygwin). That saves me the step of having to open one when I want to query my reading list. I also have some aliases that speed things up. For instance, if I want to edit my reading list in Sublime Text, I simply type “reading” at the command line, which opens the file in Sublime Text.
But what about querying the list? Well that is pretty easy, too. Here are some examples:
All of the books I’ve read in 2014
At the command line, I simply type:
grep 2014 reading.txt
and get something that looks like this in return:
The number of books I read in 2014
Ah, but what if I want to know the number of books I read without needed to see the full list? I can type,
grep 2014 reading.txt | wc -l
The wc -l at the end filters the output through the word count (wc) command and gets the number of lines in the results. Since I have one line per book the resulting number is the number of books in the query:
How many audiobooks have I listened to?
The queries don’t have to be by year. I started listening to audiobooks back in early 2013. How many have I listened to since?
grep @ reading.txt | wc -l
Turns out the answer is 78:
How many Stephen King books have I read?
Regular readers know that I am a big fan of Stephen King. So how many times have I read Stephen King?
grep "Stephen King" reading.txt | wc -l
The answer is 66. Of course, some of these I have read more than once. So…
How many Stephen King books have I read more than once?
This one is only slightly more complicated. To get the answer, I run this command:
grep "Stephen King" reading.txt | grep -F ^ | wc -l
Which basically says, “Search for the term ‘Stephen King’ in reading.txt, and then take the results and search for the ^ symbol, which is my designator for a re-read, and finally count the resulting lines.
The number of times I’ve re-read Stephen King books is 16.
To see the actual books I’ve re-read, I can just leave off the final line count search, and do this:
grep "Stephen King" reading.txt | grep -F ^
Below are the results for both queries:
How many Isaac Asimov books have I read?
Turns out that at 66 books, Stephen King is not the author I’ve read most of all. That honor (so far) goes to Isaac Asimov:
grep "Isaac Asimov" reading.txt | wc -l
Since 1996, I have read 118 Isaac Asimov books. But in truth, it’s been a while now since I read an Asimov book.
When was the last time I read an Isaac Asimov book?
For that I can use the UNIX tail command:
grep "Isaac Asimov" reading.txt | tail -n1
This simply returns all of the lines from my reading list that match “Isaac Asimov” and then looks at just the last line in the results (that’s what the tail -n1 does). The last time I finished an Isaac Asimov book was on April 24, 2012. You can also see what the book was:
The beauty of this system is that it is by far the easiest system to use and maintain of all of the systems I’ve tried over the last 20 years. There is no complex database to maintain. I just edit a text file. I keep that text file pretty simple, including only the information that I find useful. And I don’t even have to write any code. I can use simple built-in command line tools to ask the questions that I frequently ask. With a little practice, these commands become second nature, and for the purposes of my reading list, they are much faster than a database.
This saves me a ton of time. I used to spend hours in a week working on a reading list database. It wasn’t entirely wasted, as the things I learned there I was able to use elsewhere. But with my time at a premium, simple text files have been a huge time-saver.
Why not use a system like Goodreads or Library Thing?
For a while, I used both Goodreads and LibraryThings to track what I read, but I found that neither system was exactly what I was looking for. Both systems are overkill in terms of data. And they had limits when I last used them. In either case, I grew to feel that they just didn’t work the way I did, which is why I don’t use them today.
My reading.txt file is my authoritative source for my reading list today. The file is available in my Public Dropbox folder. It is also rendered on this site through a script I wrote to pretty it up for public consumption. It is accessible to anyone who wants to see it.