Before getting into the details of how to run Ledger, it will be easier to introduce the features in the context of their typical usage. To that end, this section presents a series of recipes, gradually introducing all of the command-line features of Ledger.
For the purpose of these examples, assume the environment variable LEDGER is set to the file sample.dat (which is included in the distribution), and that the contents of that file are:
= /^Expenses:Books/ (Liabilities:Taxes) -0.10 ~ Monthly Assets:Bank:Checking $500.00 Income:Salary 2004/05/01 * Checking balance Assets:Bank:Checking $1,000.00 Equity:Opening Balances 2004/05/01 * Investment balance Assets:Brokerage 50 AAPL @ $30.00 Equity:Opening Balances 2004/05/14 * Pay day Assets:Bank:Checking $500.00 Income:Salary 2004/05/27 Book Store Expenses:Books $20.00 Liabilities:MasterCard 2004/05/27 (100) Credit card company Liabilities:MasterCard $20.00 Assets:Bank:Checking
This sample file demonstrates a basic principle of accounting which it is recommended you follow: Keep all of your accounts under five parent Assets, Liabilities, Income, Expenses and Equity. It is important to do so in order to make sense out of the following examples.
Ledger has seven basic commands, but by far the most often used are balance and register. To see a summary balance of all accounts, use:
ledger bal
bal is a short-hand for balance. This command prints out the summary totals of the five parent accounts used in sample.dat:
$1,480.00 50 AAPL Assets $-2,500.00 Equity $20.00 Expenses $-500.00 Income $-2.00 Liabilities -------------------- $-1,502.00 50 AAPL
None of the child accounts are shown, just the parent account totals. We can see that in ‘Assets’ there is $1,480.00, and 50 shares of Apple stock. There is also a negative grand total. Usually the grand total is zero, which means that all accounts balance1. In this case, since the 50 shares of Apple stock cost $1,500.00 dollars, then these two amounts balance each other in the grand total. The extra $2.00 comes from a virtual transaction being added by the automatic entry at the top of the file. The entry is virtual because the account name was surrounded by parentheses in an automatic entry. Automatic entries will be discussed later, but first let's remove the virtual transaction from the balance report by using the --real option:
ledger --real bal
Now the report is:
$1,480.00 50 AAPL Assets $-2,500.00 Equity $20.00 Expenses $-500.00 Income -------------------- $-1,500.00 50 AAPL
Since the liability was a virtual transaction, it has dropped from the report and we see that final total is balanced.
But we only know that it balances because sample.dat is quite simple, and we happen to know that the 50 shares of Apple stock cost $1,500.00. We can verify that things really balance by reporting the Apple shares in terms of their cost, instead of their quantity. To do this requires the --basis, or -B, option:
ledger --real -B bal
This command reports:
$2,980.00 Assets $-2,500.00 Equity $20.00 Expenses $-500.00 Income
With the basis cost option, the grand total has disappeared, as it is now zero. The confirms that the cost of everything balances to zero, which must always be true. Reporting the real basis cost should never yield a remainder2.
The totals reported by the balance command are only the topmost parent accounts. To see the totals of all child accounts as well, use the -s option:
ledger --real -B -s bal
This reports:
$2,980.00 Assets $1,480.00 Bank:Checking $1,500.00 Brokerage $-2,500.00 Equity:Opening Balances $20.00 Expenses:Books $-500.00 Income:Salary
This shows that the ‘Assets’ total is made up from two child account, but that the total for each of the other accounts comes from one child account.
Sometimes you may have a lot of children, nested very deeply, but only
want to report the first two levels. This can be done with a display
predicate, using a value expression. In the value expression,
T
represents the reported total, and l
is the display
level for the account:
ledger --real -B -d "T&l<=2" bal
This reports:
$2,980.00 Assets $1,480.00 Bank $1,500.00 Brokerage $-2,500.00 Equity:Opening Balances $20.00 Expenses:Books $-500.00 Income:Salary
Instead of reporting ‘Bank:Checking’ as a child of ‘Assets’, it report only ‘Bank’, since that account is a nesting level of 2, while ‘Checking’ is at level 3.
To review the display predicate used—T&l<=2
—this rather
terse expression means: Display an account only if it has a non-zero
total (T
), and its nesting level is less than or equal to 2
(l<=2
).
While reporting the totals for all accounts can be useful, most often you will want to check the balance of a specific account or accounts. To do this, put one or more account names after the balance command. Since these names are really regular expressions, you can use partial names if you wish:
ledger bal checking
Reports:
$1,480.00 Assets:Bank:Checking
Any number of names may be used:
ledger bal checking broker liab
Reports:
$1,480.00 Assets:Bank:Checking 50 AAPL Assets:Brokerage $-2.00 Liabilities
In this case no grand total is reported, because you are asking for specific account balances.
For those comfortable with regular expressions, any Perl regexp is allowed:
ledger bal ^assets.*checking ^liab
Reports:
$1,480.00 Assets:Bank:Checking $-2.00 Liabilities:Taxes
While the balance command can be very handy for checking account totals, by far the most powerful of Ledger's reporting tools is the register command. In fact, internally both commands use the same logic, but report the results differently: balance shows the summary totals, while register reports each transaction and how it contributes to that total.
Paradoxically, the most basic form of register is almost never used, since it displays every transaction:
ledger reg
reg is a short-hand for register. This command reports:
2004/05/01 Checking balance Assets:Bank:Checking $1,000.00 $1,000.00 Equity:Opening Balan.. $-1,000.00 0 2004/05/01 Investment balance Assets:Brokerage 50 AAPL 50 AAPL Equity:Opening Balan.. $-1,500.00 $-1,500.00 50 AAPL 2004/05/14 Pay day Assets:Bank:Checking $500.00 $-1,000.00 50 AAPL Income:Salary $-500.00 $-1,500.00 50 AAPL 2004/05/27 Book Store Expenses:Books $20.00 $-1,480.00 50 AAPL Liabilities:MasterCard $-20.00 $-1,500.00 50 AAPL (Liabilities:Taxes) $-2.00 $-1,502.00 50 AAPL 2004/05/27 Credit card company Liabilities:MasterCard $20.00 $-1,482.00 50 AAPL Assets:Bank:Checking $-20.00 $-1,502.00 50 AAPL
This rather verbose output shows every account transaction in sample.dat, and how it affects the running total. The final total is identical to what we saw with the plain balance command. To see how things really balance, we can use ‘--real -B’, just as we did with balance:
ledger --real -B reg
Reports:
2004/05/01 Checking balance Assets:Bank:Checking $1,000.00 $1,000.00 Equity:Opening Balan.. $-1,000.00 0 2004/05/01 Investment balance Assets:Brokerage $1,500.00 $1,500.00 Equity:Opening Balan.. $-1,500.00 0 2004/05/14 Pay day Assets:Bank:Checking $500.00 $500.00 Income:Salary $-500.00 0 2004/05/27 Book Store Expenses:Books $20.00 $20.00 Liabilities:MasterCard $-20.00 0 2004/05/27 Credit card company Liabilities:MasterCard $20.00 $20.00 Assets:Bank:Checking $-20.00 0
Here we see that everything balances to zero in the end, as it must.
The most common use of the register command is to summarize transactions based on the account(s) they affect. Using sample.dat as as example, we could look at all book purchases using:
ledger reg books
Reports:
2004/05/29 Book Store Expenses:Books $20.00 $20.00
If a double-dash (‘--’) occurs in the list of regular expressions, any following arguments are matched against payee names, instead of account names:
ledger reg ^liab -- credit
Reports:
2004/05/29 Credit card company Liabilities:MasterCard $20.00 $20.00
There are many reporting options for tailoring which transactions are found, and also how to summarize the various amounts and totals that result. These are plumbed in greater depth below.
Although the easiest way to use the register is to report all the transactions affecting a set of accounts, it can often result in more information than you want. To cope with an ever-growing amount of data, there are several options which can help you pinpoint your report to exactly the transactions that interest you most. This is called the “calculation” phase of Ledger. All of its related options are documented under --help-calc.
--current(-c) displays entries occurring on or before the current date. Any entry recorded for a future date will be ignored, as if it had not been seen. This is useful if you happen to pre-record entries, but still wish to view your balances in terms of what is available today.
--begin DATE (-b DATE) limits the report to only those entries occurring on or after DATE. The running total in the register will start at zero with the first transaction, even if there are earlier entries.
To limit the display only, but still add earlier transactions to the running total, use the display expression ‘-d 'd>=[DATE]'’):
ledger --basis -b may -d 'd>=[5/14]' reg ^assets
Reports:
2004/05/14 Pay day Assets:Bank:Checking $500.00 $3,000.00 2004/05/27 Credit card company Assets:Bank:Checking $-20.00 $2,980.00
In this example, the displayed transactions start from ‘5/14’, but the calculated total starts from the beginning of ‘may’.
--end DATE (-e DATE) states when reporting should end, both calculation and display. The ending date is inclusive.
The DATE argument to the -b and -e options can be rather flexible. Assuming the current date to be November 15, 2004, then all of the following are equivalent:
ledger -b oct bal ledger -b "this oct" bal ledger -b 2004/10 bal ledger -b 10 bal ledger -b last bal ledger -b "last month" bal
To constrain the report to a specific time period, use --period (-p). A time period may have both a beginning and an end, or neither, as well as a specified interval. Here are a few examples:
ledger -p 2004 bal ledger -p august bal ledger -p "from aug to oct" bal ledger -p "daily from 8/1 to 8/15" bal ledger -p "weekly since august" bal ledger -p "monthly from feb to oct" bal ledger -p "quarterly in 2004" bal ledger -p yearly bal
See Period expressions for more on syntax. Also, all of the options -b, -e and -p may be used together, but whatever information occurs last takes priority. An example of such usage (in a script, perhaps) would be:
ledger -b 2004 -e 2005 -p monthly reg ^expenses
This command is identical to:
ledger -p "monthly in 2004" reg ^expenses
The transactions within a period may be sorted using --period-sort, which takes a value expression. This is similar to the --sort option, except that it sorts within each period entry, rather than sorting all transactions in the report. See the documentation on --sort below for more details.
By default, all regular transactions are included in each report. To limit the report to certain kinds of transactions, use one or more of the following options:
Cleared transactions are indicated by an asterix placed just before the payee name in a transaction. The meaning of this flag is up to the user, but typically it means that an entry has been seen on a financial statement. Pending transactions use an exclamation mark in the same position, but are mainly used only by reconciling software. Uncleared transactions are for things like uncashed checks, credit charges that haven't appeared on a statement yet, etc.
Real transactions are all non-virtual transactions, where the account name is not surrounded by parentheses or square brackets. Virtual transactions are useful for showing a transfer of money that never really happened, like money set aside for savings without actually transferring it from the parent account.
Actual transactions are those not generated, either as part of an automated entry, or a budget or forecast report. A useful of when you might like to filter out generated transactions is with a budget:
ledger --budget --actual reg ^expenses
This command outputs all transactions affecting a budgeted account, but without subtracting the budget amount (because the generated transactions are suppressed with --actual). The report shows how much you actually spent on budgeted items.
Normally, a register report includes only the transactions that match the regular expressions specified after the command word. For example, to report all expenses:
ledger reg ^expenses
This reports:
2004/05/29 Book Store Expenses:Books $20.00 $20.00
Using --related (-r) reports the transactions that did not match your query, but only in entries that otherwise would have matched. This has the effect of indicating where money came from, or when to:
ledger -r reg ^expenses
Reports:
2004/05/29 Book Store Liabilities:MasterCard $20.00 $20.00
There is more information about budgeting and forecasting in Budgeting and forecasting. Basically, if you have any period entries in your ledger file, you can use these options. A period entry looks like:
~ Monthly Assets:Bank:Checking $500.00 Income:Salary
The difference from a regular entry is that the first line begins with a tilde (~), and instead of a payee there's a period expression (Period expressions). Otherwise, a period entry is in every other way the same as a regular entry.
With such an entry in your ledger file, the --budget option will report only transactions that match a budgeted account. Using sample.dat from above:
ledger --budget reg ^income
Reports:
2004/05/01 Budget entry Income:Salary $500.00 $500.00 2004/05/14 Pay day Income:Salary $-500.00 0
The final total is zero, indicating that the budget matched exactly for the reported period. Budgeting is most often helpful with period reporting; for example, to show monthly budget results use --budget -p monthly.
The --add-budget option reports all matching transactions in addition to budget transactions; while --unbudgeted shows only those that don't match a budgeted account. To summarize:
A report with the --forecast option will add budgeted transactions while the specified value expression is true. For example:
ledger --forecast 'd<[2005] reg ^income
Reports:
2004/05/14 Pay day Income:Salary $-500.00 $-500.00 2004/12/01 Forecast entry Income:Salary $-500.00 $-1,000.00 2005/01/01 Forecast entry Income:Salary $-500.00 $-1,500.00
The date this report was made was November 5, 2004; the reason the first forecast entry is in december is that forecast entries are only added for the future, and they only stop after the value expression has matched at least once, which is why the January entry appears. A forecast report can be very useful for determining when money will run out in an account, or for projecting future cash flow:
ledger --forecast 'd<[2008]' -p yearly reg ^inc ^exp
This reports balances projected income against projected expenses, showing the resulting total in yearly intervals until 2008. For the case of sample.dat, which has no budgeted expenses, the result of the above command (in November 2004) is:
2004/01/01 - 2004/12/31 Income:Salary $-1,000.00 $-1,000.00 Expenses:Books $20.00 $-980.00 2005/01/01 - 2005/12/31 Income:Salary $-6,000.00 $-6,980.00 2006/01/01 - 2006/12/31 Income:Salary $-6,000.00 $-12,980.00 2007/01/01 - 2007/12/31 Income:Salary $-6,000.00 $-18,980.00 2008/01/01 - 2008/01/01 Income:Salary $-500.00 $-19,480.00
Value expressions can be quite complex, and are treated more fully in Value expressions. They can be used for limiting a report with --limit (-l). The following command report income since august, but expenses since october:
ledger -l '(/income/&d>=[aug])|(/expenses/&d>=[oct])' reg
The basic form of this value expression is ‘(A&B)|(A&B)’. The ‘A’ in each part matches against an account name with ‘/name/’, while each ‘B’ part compares the date of the transaction (‘d’) with a specified month. The resulting report will contain only transactions which match the value expression.
Another use of value expressions is to calculate the amount reported for each line of a register report, or for computing the subtotal of each account shown in a balance report. This example divides each transaction amount by two:
ledger -t 'a/2' reg ^exp
The -t option doesn't affect the running total, only how the transaction amount is displayed. To change the running total, use -T. In that case, you will likely want to use the total (‘O’) instead of the amount (‘a’):
ledger -T 'O/2' reg ^exp
Even after filtering down your data to just the transactions you're interested in, the default reporting method of one transaction per line is often still too much. To combat this complexity, it is possible to ask Ledger to report the details to you in many different forms, summarized in various ways. This is the “display” phase of Ledger, and is documented under --help-disp.
When multiple transactions relate to a single entry, they are reported as part of that entry. For example, in the case of sample.dat:
ledger reg -- book
Reports:
2004/05/29 Book Store Expenses:Books $20.00 $20.00 Liabilities:MasterCard $-20.00 0 (Liabilities:Taxes) $-2.00 $-2.00
All three transactions are part of one entry, and as such the entry details are printed only once. To report every entry on a single line, use -n to collapse entries with multiple transactions:
ledger -n reg -- book
Reports:
2004/05/29 Book Store <Total> $-2.00 $-2.00
In the balance report, -n causes the grand total not to be displayed at the bottom of the report.
If an account occurs more than once in a report, it is possible to combine them all and report the total per-account, using -s. For example, this command:
ledger -B reg ^assets
Reports:
2004/05/01 Checking balance Assets:Bank:Checking $1,000.00 $1,000.00 2004/05/01 Investment balance Assets:Brokerage $1,500.00 $2,500.00 2004/05/14 Pay day Assets:Bank:Checking $500.00 $3,000.00 2004/05/27 Credit card company Assets:Bank:Checking $-20.00 $2,980.00
But if the -s option is added, the result becomes:
2004/05/01 - 2004/05/29 Assets:Bank:Checking $1,480.00 $1,480.00 Assets:Brokerage $1,500.00 $2,980.00
When account subtotaling is used, only one entry is printed, and the date and name reflect the range of the combined transactions.
With -P, transactions relating to the same payee are combined. In this case, the date of the combined entry is that of the latest transaction.
-x changes the payee name for each transaction to be the same as the commodity it uses. This can be especially useful combined with other options, like -P. For example:
ledger -Px reg ^assets
Reports:
2004/05/29 $ Assets:Bank:Checking $1,480.00 $1,480.00 2004/05/01 AAPL Assets:Brokerage 50 AAPL $1,480.00 50 AAPL
This reports shows the subtotal for each commodity held, and where it is located. To see the basis cost, or initial investment, add -B. Applied to the example above:
2004/05/29 $ Assets:Bank:Checking $1,480.00 $1,480.00 2004/05/01 AAPL Assets:Brokerage $1,500.00 $2,980.00
The only other options which affect summarized totals is -E, which works only in the balance report. In this case, it shows matching accounts with a zero a balance, which are ordinarily excluded. This can be useful to see all the accounts involved in a report, even if some have no total.
Although the -p option (also --period) is much more versatile, there are other options to make the most common period reports easier:
There is one kind of period report cannot be done with -p. This is the --dow, or “days of the week” report, which shows summarized totals for each day of the week. The following examples shows a “day of the week” report of income and expenses:
ledger --dow reg ^inc ^exp
Reports:
2004/05/27 Thursdays Expenses:Books $20.00 $20.00 2004/05/14 Fridays Income:Salary $-500.00 $-480.00
The transactions displayed in a report are shown in the same order as they appear in the ledger file. To change the order and sort a report, use the --sort option. --sort takes a value expression to determine the value to sort against, making it possible to sort according to complex criteria. Here are some simple and useful examples:
ledger --sort d reg ^exp # sort by date ledger --sort t reg ^exp # sort by amount total ledger --sort -t reg ^exp # reverse sort by amount total ledger --sort Ut reg ^exp # sort by abs amount total
For the balance report, you will want to use ‘T’ instead of ‘t’:
ledger --sort T reg ^exp # sort by amount total ledger --sort -T reg ^exp # reverse sort by amount total ledger --sort UT reg ^exp # sort by abs amount total
The --sort options sorts all transactions in a report. If periods are used (such as --monthly), this can get somewhat confusing. In that case, you'll probably want to sort within periods using --period-sort instead of --sort.
And if the register seems too cramped, and you have a lot of screen real estate, you can use -w to format the report within 132 acolumns, instead of 80. You are more likely then to see full payee and account names, as well as properly formatted totals when long-named commodities are used.
If you want only the first or last N entries to be printed—which can be very useful for viewing the last 10 entries in your checking account, while also showing the cumulative balance from all entries—use the --head and/or --tail options. The two options may be used simultaneously, for example:
ledger --tail 20 reg checking
If the output from your command is very long, Ledger can output the data to a pager utility, such as more or less:
ledger --pager /usr/bin/less reg checking
To see the running total changed to a running average, use -A. The final transaction's total will be the overall average of all displayed transactions. The works in conjunction with period reporting, so that you can see your monthly average expenses with:
ledger -AM reg ^expenses:food ledger -AMn reg ^expenses
This works in the balance report too:
ledger -AM bal ^expenses:food ledger -AMs bal ^expenses
The -D option changes the running average into a deviation from the running average. This only makes sense in the register report, however.
ledger -DM reg ^expenses:food
In the balance report only, -% changes the reported totals into a percentage of the parent account. This kind of report is confusing if negative amounts are involved, and doesn't work at all if multiple commodities occur in an account's history. It has a somewhat limited usefulness, therefore, but in certain cases it can be handy, such as reviewing overall expenses:
ledger -%s -S T bal ^expenses
Normally in the xml report, only transaction amounts are printed. To include the running total under a ‘<total>’ tag, use --totals. This does not affect any other report.
In the register report only, the output can be changed with -j to show only the date and the amount—without commodities. This only makes sense if a single commodity appears in the report, but can be quite useful for scripting, or passing the data to Gnuplot. To show only the date and running total, use -J.
With -d you can decide which transactions (or accounts in the balance report) are displayed, according to a value expression. The computed total is not affected, only the display. This can be very useful for shortening a report without changing the running total:
ledger -d 'd>=[last month]' reg checking
This command shows the checking account's register, beginning from last month, but with the running total reflecting the entire history of the account.
When dates are printed in any report, the default format is
‘%Y/%m/%d’, which yields dates of the form ‘YYYY/mm/dd’.
This can be changed with -y, whose argument is a
strftime
string—see your system's C library documentation for
the allowable codes. Mostly you will want to use ‘%Y’, ‘%m’
and ‘%d’, in whatever combination is convenient for your locale.
To change the format of the entire reported line, use -F. It supports quite a large number of options, which are all documented in Format strings. In addition, each specific kind of report (except for xml) can be changed using one of the following options:
%20T %2_%-a\n
%D %-.20P %-.22A %12.66t %12.80T\n%/%32|%-.22A %12.66t %12.80T\n
%D %-.35P %-.38A %22.108t %22.132T\n%/%48|%-.38A %22.108t %22.132T\n
%D %(St)\n
%D %(ST)\n
\n%D %Y%C%P\n %-34W %12o%n\n%/ %-34W %12o%n\n
\n%D %Y%C%P\n%/ %-34W %12t\n
%D %-.35P %-.38A %22.108t %22.132T\n%/%48|%-.38A %22.108t %22.132T\n
If your ledger file uses the standard top-level accounts: Assets, Liabilities, Income, Expenses, Equity: then the following queries will enable you to generate some typical accounting reports from your data.
Your net worth can be determined by balancing assets against liabilities:
ledger bal ^assets ^liab
By removing long-term investment and loan accounts, you can see your current net liquidity (or liquid net worth):
ledger bal ^assets ^liab -retirement -brokerage -loan
Balancing expenses against income yields your cash flow, or net profit/loss:
ledger bal ^exp ^inc
In this case, if the number is positive it means you spent more than you earned during the report period.
The most often used command is the “balance” command:
export LEDGER=/home/johnw/doc/ledger.dat ledger balance
Here I've set my Ledger environment variable to point to where my ledger file is hiding. Thereafter, I needn't specify it again.
The balance command prints out the summarized balances of all my top-level accounts, excluding sub-accounts. In order to see the balances for a specific account, just specify a regular expression after the balance command:
ledger balance expenses:food
This will show all the money that's been spent on food, since the beginning of the ledger. For food spending just this month (September), use:
ledger -p sep balance expenses:food
Or maybe you want to see all of your assets, in which case the -s (show sub-accounts) option comes in handy:
ledger -s balance ^assets
To exclude a particular account, use a regular expression with a leading minus sign. The following will show all expenses, but without food spending:
ledger balance expenses -food
There is no built-in way to report transaction amounts or account balances in terms of percentages