Filtering and searching in hledger

I am an advocate of plaintext accounting, and hledger is my go-to tool for this. A good summary of WTF and why on their landing page. All of the various bank accounts and cards I use have some sort of CSV or XML export function. Feeding these in to hledger gives me a powerful direct view on my finances that I can analyze in aggregate for budgeting and planning, but also zoom in to a specific transaction or range of transactions.

The manual is extensive, these are just a few quick notes on searching and filtering, It deals with the CLI and TUI interfaces. I haven't tried in hledger-web, but if you have please let me know and I'll update this post.

Credits and debits

Hledger calls this filtering by direction. In the TUI, hit forward slash / (vim syntax) and type in your query: amt:>0 for credits or amt:<0 for debits (i.e. greater or less than zero).

On the command line, it's the same query, just bolt it on the end as an argument:

hledger reg 'amt:>0' # for credits
hledger reg 'amt:<0' # for debits

And we get our nice Terminal table format:

Results

2024-09-12 Apple Pay Top-Up by *..  accounts:revolut           €10.00        €10.00
2024-10-12 Apple Pay Top-Up by *..  accounts:revolut           €90.00       €100.00
2024-10-12 SuperValu                ex:be:food:groceries        €6.00       €106.00
2024-10-12 Mrs Robinsons            expenses:unknown           €20.00       €126.00
2024-10-12 The Burnaby              expenses:unknown           €11.60       €137.60
2024-10-12 The Burnaby              expenses:unknown           €11.30       €148.90
2024-10-12 Jokers                   expenses:unknown            €9.00       €157.90
2024-10-13 Apple Pay Top-Up by *..  accounts:revolut           €50.00       €207.90
2024-10-13 Tesco                    ex:be:food:groceries        €6.00       €213.90
2024-10-13 Tesco                    ex:be:food:groceries       €27.21       €241.11
...

This also workd for hledger print and other subcommands …

Amount

As you might expect, it's pretty much the same query:

hledger reg 'amt:>100'

Results

Curiously, it returns results plus-or-minus zero (i.e. absolute value):

2024-10-24 Apple Pay Top-Up by *6827  accounts:revolut         €120.00       €120.00
                                      zerosum:transfers       €-120.00             0
2024-10-25 Apple Pay Top-Up by *6827  accounts:revolut         €150.00       €150.00
                                      zerosum:transfers       €-150.00             0
2024-10-25 Il Caffe Di Napoli         accounts:revolut         €-61.90       €-61.90
                                      expenses:unknown          €61.90             0
2024-10-31 Exchanged to EUR           accounts:revolut         €150.00       €150.00
                                      income:unknown          €-150.00             0
2024-11-01 Il Caffe Di Napoli         accounts:revolut         €-64.85       €-64.85
                                      expenses:unknown          €64.85             0
...

Consequently you're seeing the double-entry bookkeeping effect in full swing above.

To get transactions in a range and only debits (or credits), we need a compound query! After much head-scratching, in the end it was as simple as adding (and separatings) arguments:

hledger reg 'amt:>100' 'amt:<0'

Results

2024-05-29    Maxi Zoo              accounts:revolut        €-121.63     €752.09
2024-05-30    Interesting Tra..     accounts:current        €-150.00     €902.09
2024-05-30    Interesting Tra..     accounts:current        €-150.00     €052.09
2024-05-30    *INET VISA            accounts:current        €-500.00     €552.09
2024-05-30    PAYMENT THANK YOU     zerosum:transfers       €-500.00     €052.09
2024-05-31    Auto Somethingo..     zerosum:transfers       €-150.00     €202.09
2024-06-01    VDP-DEXTERS INS..     accounts:current        €-416.50     €618.59
2024-06-01    Revolting-Foods..     accounts:current        €-150.00     €768.59
...

Range of amounts

It's the same as above, we can triple-load our amount (and direction) filters:

hledger reg 'amt:>100' 'amt:<0' 'amt:<500'

Show only specific account(s)

You probably already know this one:

hledger reg accounts:current

-or-

hledger ui accounts:current

Description

Instead of amt: we use desc:. Nicely, it will accept a regular expressions (regex) too!

hledger reg desc:brother # any description containing the word 'brother'
hledger print desc:"\<[0-9]{2}\>" # regular expression: any two digits surrounded by a word boundary

Results

2022-11-07 * Street 66  ; CARD_PAYMENT Current
    accounts:revolut              €-23.3
    expenses:entertainment:food   €23.30

2022-11-18 * Street 66  ; CARD_PAYMENT Current
    accounts:current              €-15.8
    expenses:unknown              €15.80

2023-09-03 * 39 Aungier St
    accounts:current               €-7.7
    expenses:unknown               €7.70

2024-04-08 * 29 Dunville Ave
    accounts:credit-card        €-162.62
    expenses:unknown             €162.62

Date range

I find this one particularly handy for starting the UI in a little sandbox for, say, doing my sums for the previous month. What's particularly nice is that you can give it relative dates.

Otherwise, always give it dates in ISO format1 (a good habit in life to avoid all sorts of unmitigated disasters). Sorry Americans, you're wrong about dates. If it's any consolation, us Europeans were wrong too.

hledger ui --period 'last month'  # starts hledger-ui for 1-28 February just gone (at time of writing)
hledger reg --period '2024-01-01 to 2024-12-31'   # date range in ISO format. Though in this case it would have accepted simply '2024' for the full year.

Putting it all together

Some examples:

hledger reg accounts:credit-card --period 'last month'
hledger print 'amt:<0' 'amt:>10' 'amt:<10000' accounts:revolut desc:brother --period 2024
# ^^ get full transactional data for how many times I sent my brother any amount between €10 and €10,000 in 2024
hledger reg 'amt:>0' 'desc:ryanair' accounts
# ^^ did I ever receive that refund from Ryanair to any of my accounts? (spoiler: no)

1

ISO 8601 dates follow YYYY-MM-DD format and avoids any possible ambiguity between the various date formats in use around the world. As a bonus, when sorting alphabetically it will always sort in the correct chronological order. An end to the chaos in your documents folder!