;doc: regen manuals
[ci skip]
This commit is contained in:
parent
d92351e21a
commit
7ecc42f142
@ -18,8 +18,8 @@ These do several things:
|
|||||||
.IP \[bu] 2
|
.IP \[bu] 2
|
||||||
they describe the layout and format of the CSV data
|
they describe the layout and format of the CSV data
|
||||||
.IP \[bu] 2
|
.IP \[bu] 2
|
||||||
they can customize the generated journal entries using a simple
|
they can customize the generated journal entries (transactions) using a
|
||||||
templating language
|
simple templating language
|
||||||
.IP \[bu] 2
|
.IP \[bu] 2
|
||||||
they can add refinements based on patterns in the CSV data, eg
|
they can add refinements based on patterns in the CSV data, eg
|
||||||
categorizing transactions with more detailed account names.
|
categorizing transactions with more detailed account names.
|
||||||
@ -44,70 +44,142 @@ skip 1
|
|||||||
\f[R]
|
\f[R]
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
A more complete example:
|
More examples in the EXAMPLES section below.
|
||||||
|
.SH CSV RULES
|
||||||
|
.PP
|
||||||
|
The following kinds of rule can appear in the rules file, in any order
|
||||||
|
(except for \f[C]end\f[R] which can appear only inside a conditional
|
||||||
|
block).
|
||||||
|
Blank lines and lines beginning with \f[C]#\f[R] or \f[C];\f[R] are
|
||||||
|
ignored.
|
||||||
|
.SS \f[C]skip\f[R]
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
# hledger CSV rules for amazon.com order history
|
skip N
|
||||||
|
|
||||||
# sample:
|
|
||||||
# \[dq]Date\[dq],\[dq]Type\[dq],\[dq]To/From\[dq],\[dq]Name\[dq],\[dq]Status\[dq],\[dq]Amount\[dq],\[dq]Fees\[dq],\[dq]Transaction ID\[dq]
|
|
||||||
# \[dq]Jul 29, 2012\[dq],\[dq]Payment\[dq],\[dq]To\[dq],\[dq]Adapteva, Inc.\[dq],\[dq]Completed\[dq],\[dq]$25.00\[dq],\[dq]$0.00\[dq],\[dq]17LA58JSK6PRD4HDGLNJQPI1PB9N8DKPVHL\[dq]
|
|
||||||
|
|
||||||
# skip one header line
|
|
||||||
skip 1
|
|
||||||
|
|
||||||
# name the csv fields (and assign the transaction\[aq]s date, amount and code)
|
|
||||||
fields date, _, toorfrom, name, amzstatus, amount, fees, code
|
|
||||||
|
|
||||||
# how to parse the date
|
|
||||||
date-format %b %-d, %Y
|
|
||||||
|
|
||||||
# combine two fields to make the description
|
|
||||||
description %toorfrom %name
|
|
||||||
|
|
||||||
# save these fields as tags
|
|
||||||
comment status:%amzstatus, fees:%fees
|
|
||||||
|
|
||||||
# set the base account for all transactions
|
|
||||||
account1 assets:amazon
|
|
||||||
|
|
||||||
# flip the sign on the amount
|
|
||||||
amount -%amount
|
|
||||||
\f[R]
|
\f[R]
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
For more examples, see Convert CSV files.
|
The word \[dq]skip\[dq] followed by a number (or no number, meaning 1)
|
||||||
.SH CSV RULES
|
tells hledger to ignore this many non-empty lines preceding the CSV
|
||||||
.PP
|
data.
|
||||||
The following seven kinds of rule can appear in the rules file, in any
|
|
||||||
order.
|
|
||||||
Blank lines and lines beginning with \f[C]#\f[R] or \f[C];\f[R] are
|
|
||||||
ignored.
|
|
||||||
.SS skip
|
|
||||||
.PP
|
|
||||||
\f[C]skip\f[R]\f[I]\f[CI]N\f[I]\f[R]
|
|
||||||
.PP
|
|
||||||
Skip this many non-empty lines preceding the CSV data.
|
|
||||||
(Empty/blank lines are skipped automatically.) You\[aq]ll need this
|
(Empty/blank lines are skipped automatically.) You\[aq]ll need this
|
||||||
whenever your CSV data contains header lines.
|
whenever your CSV data contains header lines.
|
||||||
|
.PP
|
||||||
|
It also has a second purpose: it can be used to ignore certain CSV
|
||||||
|
records, see conditional blocks below.
|
||||||
|
.SS \f[C]fields\f[R]
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
fields FIELDNAME1, FIELDNAME2, ...
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
A fields list (\[dq]fields\[dq] followed by one or more comma-separated
|
||||||
|
field names) is the quick way to assign CSV field values to hledger
|
||||||
|
fields.
|
||||||
|
It (a) names the CSV fields, in order (names may not contain whitespace;
|
||||||
|
fields you don\[aq]t care about can be left unnamed), and (b) assigns
|
||||||
|
them to hledger fields if you use standard hledger field names.
|
||||||
|
Here\[aq]s an example:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
# use the 1st, 2nd and 4th CSV fields as the transaction\[aq]s date, description and amount,
|
||||||
|
# ignore the 3rd, 5th and 6th fields,
|
||||||
|
# and name the 7th and 8th fields for later reference:
|
||||||
|
# 1 2 3 4 5 6 7 8
|
||||||
|
|
||||||
|
fields date, description, , amount1, , , somefield, anotherfield
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Here are the standard hledger field names:
|
||||||
|
.SS Transaction fields
|
||||||
|
.PP
|
||||||
|
\f[C]date\f[R], \f[C]date2\f[R], \f[C]status\f[R], \f[C]code\f[R],
|
||||||
|
\f[C]description\f[R], \f[C]comment\f[R] can be used to form the
|
||||||
|
transaction\[aq]s first line.
|
||||||
|
Only \f[C]date\f[R] is required.
|
||||||
|
(See also date-format below.)
|
||||||
|
.SS Posting fields
|
||||||
|
.PP
|
||||||
|
\f[C]accountN\f[R], where N is 1 to 9, sets the Nth posting\[aq]s
|
||||||
|
account name.
|
||||||
|
Most often there are two postings, so you\[aq]ll want to set
|
||||||
|
\f[C]account1\f[R] and \f[C]account2\f[R].
|
||||||
|
.PP
|
||||||
|
A number of field/pseudo-field names are available for setting posting
|
||||||
|
amounts:
|
||||||
|
.IP \[bu] 2
|
||||||
|
\f[C]amountN\f[R] sets posting N\[aq]s amount
|
||||||
|
.IP \[bu] 2
|
||||||
|
\f[C]amountN-in\f[R] and \f[C]amountN-out\f[R] can be used instead, if
|
||||||
|
the CSV has separate fields for debits and credits
|
||||||
|
.IP \[bu] 2
|
||||||
|
\f[C]currencyN\f[R] sets a currency symbol to be left-prefixed to the
|
||||||
|
amount, useful if the CSV provides that as a separate field
|
||||||
|
.IP \[bu] 2
|
||||||
|
\f[C]balanceN\f[R] sets a (separate) balance assertion amount (or when
|
||||||
|
no posting amount is set, a balance assignment)
|
||||||
|
.PP
|
||||||
|
If you write these with no number (\f[C]amount\f[R],
|
||||||
|
\f[C]amount-in\f[R], \f[C]amount-out\f[R], \f[C]currency\f[R],
|
||||||
|
\f[C]balance\f[R]), it means posting 1.
|
||||||
|
Also, if you set an amount for posting 1 only, a second posting that
|
||||||
|
balances the transaction will be generated automatically.
|
||||||
|
This helps support CSV rules created before hledger 1.16.
|
||||||
|
.PP
|
||||||
|
Finally, \f[C]commentN\f[R] sets a comment on the Nth posting.
|
||||||
|
Comments can of course contain tags.
|
||||||
|
.SS \f[C](field assignment)\f[R]
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
HLEDGERFIELDNAME FIELDVALUE
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Instead of or in addition to a fields list, you can assign a value to a
|
||||||
|
hledger field by writing its name (any of the standard names above)
|
||||||
|
followed by a text value.
|
||||||
|
The value may contain interpolated CSV fields, referenced by their
|
||||||
|
1-based position in the CSV record (\f[C]%N\f[R]), or by the name they
|
||||||
|
were given in the fields list (\f[C]%CSVFIELDNAME\f[R]).
|
||||||
Eg:
|
Eg:
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
# ignore the first CSV line
|
# set the amount to the 4th CSV field, with \[dq] USD\[dq] appended
|
||||||
skip 1
|
amount %4 USD
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
# combine three fields to make a comment, containing note: and date: tags
|
||||||
|
comment note: %somefield - %anotherfield, date: %1
|
||||||
\f[R]
|
\f[R]
|
||||||
.fi
|
.fi
|
||||||
.SS date-format
|
|
||||||
.PP
|
.PP
|
||||||
\f[C]date-format\f[R]\f[I]\f[CI]DATEFMT\f[I]\f[R]
|
Interpolation strips any outer whitespace, so a CSV value like
|
||||||
|
\f[C]\[dq] 1 \[dq]\f[R] becomes \f[C]1\f[R] when interpolated (#1051).
|
||||||
|
Note you can only interpolate CSV fields, not the hledger fields being
|
||||||
|
assigned to; for more on this, see TIPS.
|
||||||
|
.SS \f[C]date-format\f[R]
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
date-format DATEFMT
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
.PP
|
.PP
|
||||||
When your CSV date fields are not formatted like \f[C]YYYY/MM/DD\f[R]
|
This is a helper for the \f[C]date\f[R] (and \f[C]date2\f[R]) fields.
|
||||||
(or \f[C]YYYY-MM-DD\f[R] or \f[C]YYYY.MM.DD\f[R]), you\[aq]ll need to
|
If your CSV dates are not formatted like \f[C]YYYY-MM-DD\f[R],
|
||||||
specify the format.
|
\f[C]YYYY/MM/DD\f[R] or \f[C]YYYY.MM.DD\f[R], you\[aq]ll need to specify
|
||||||
DATEFMT is a strptime-like date parsing pattern, which must parse the
|
the format by writing \[dq]date-format\[dq] followed by a strptime-like
|
||||||
date field values completely.
|
date parsing pattern, which must parse the date field values completely.
|
||||||
Examples:
|
Examples:
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
@ -119,7 +191,7 @@ date-format %m/%d/%Y
|
|||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
# for dates like \[dq]6/11/2013\[dq] (note the - to make leading zeros optional):
|
# for dates like \[dq]6/11/2013\[dq]. The - allows leading zeros to be optional.
|
||||||
date-format %-d/%-m/%Y
|
date-format %-d/%-m/%Y
|
||||||
\f[R]
|
\f[R]
|
||||||
.fi
|
.fi
|
||||||
@ -137,90 +209,47 @@ date-format %Y-%h-%d
|
|||||||
date-format %-m/%-d/%Y %l:%M %p
|
date-format %-m/%-d/%Y %l:%M %p
|
||||||
\f[R]
|
\f[R]
|
||||||
.fi
|
.fi
|
||||||
.SS field list
|
.SS \f[C]if\f[R]
|
||||||
.PP
|
|
||||||
\f[C]fields\f[R]\f[I]\f[CI]FIELDNAME1\f[I]\f[R],
|
|
||||||
\f[I]\f[CI]FIELDNAME2\f[I]\f[R]...
|
|
||||||
.PP
|
|
||||||
This (a) names the CSV fields, in order (names may not contain
|
|
||||||
whitespace; uninteresting names may be left blank), and (b) assigns them
|
|
||||||
to journal entry fields if you use any of these standard field names:
|
|
||||||
\f[C]date\f[R], \f[C]date2\f[R], \f[C]status\f[R], \f[C]code\f[R],
|
|
||||||
\f[C]description\f[R], \f[C]comment\f[R], \f[C]account1\f[R],
|
|
||||||
\f[C]account2\f[R], \f[C]amount\f[R], \f[C]amount-in\f[R],
|
|
||||||
\f[C]amount-out\f[R], \f[C]currency\f[R], \f[C]balance\f[R],
|
|
||||||
\f[C]balance1\f[R], \f[C]balance2\f[R].
|
|
||||||
Eg:
|
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
# use the 1st, 2nd and 4th CSV fields as the entry\[aq]s date, description and amount,
|
if PATTERN
|
||||||
# and give the 7th and 8th fields meaningful names for later reference:
|
RULE
|
||||||
#
|
|
||||||
# CSV field:
|
if
|
||||||
# 1 2 3 4 5 6 7 8
|
PATTERN
|
||||||
# entry field:
|
PATTERN
|
||||||
fields date, description, , amount, , , somefield, anotherfield
|
PATTERN
|
||||||
\f[R]
|
RULE
|
||||||
.fi
|
RULE
|
||||||
.SS field assignment
|
|
||||||
.PP
|
|
||||||
\f[I]\f[CI]ENTRYFIELDNAME\f[I]\f[R] \f[I]\f[CI]FIELDVALUE\f[I]\f[R]
|
|
||||||
.PP
|
|
||||||
This sets a journal entry field (one of the standard names above) to the
|
|
||||||
given text value, which can include CSV field values interpolated by
|
|
||||||
name (\f[C]%CSVFIELDNAME\f[R]) or 1-based position (\f[C]%N\f[R]).
|
|
||||||
Eg:
|
|
||||||
.IP
|
|
||||||
.nf
|
|
||||||
\f[C]
|
|
||||||
# set the amount to the 4th CSV field with \[dq]USD \[dq] prepended
|
|
||||||
amount USD %4
|
|
||||||
\f[R]
|
|
||||||
.fi
|
|
||||||
.IP
|
|
||||||
.nf
|
|
||||||
\f[C]
|
|
||||||
# combine three fields to make a comment (containing two tags)
|
|
||||||
comment note: %somefield - %anotherfield, date: %1
|
|
||||||
\f[R]
|
\f[R]
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
Field assignments can be used instead of or in addition to a field list.
|
Conditional blocks apply one or more rules to CSV records which are
|
||||||
|
matched by any of the PATTERNs.
|
||||||
|
This allows transactions to be customised or categorised based on
|
||||||
|
patterns in the data.
|
||||||
.PP
|
.PP
|
||||||
Note, interpolation strips any outer whitespace, so a CSV value like
|
A single pattern can be written on the same line as the \[dq]if\[dq]; or
|
||||||
\f[C]\[dq] 1 \[dq]\f[R] becomes \f[C]1\f[R] when interpolated (#1051).
|
multiple patterns can be written on the following lines, non-indented.
|
||||||
.SS conditional block
|
|
||||||
.PP
|
.PP
|
||||||
\f[C]if\f[R] \f[I]\f[CI]PATTERN\f[I]\f[R]
|
Patterns are case-insensitive regular expressions which try to match any
|
||||||
.PD 0
|
part of the whole CSV record.
|
||||||
.P
|
It\[aq]s not yet possible to match within a specific field.
|
||||||
.PD
|
Note the CSV record they see is close but not identical to the one in
|
||||||
\ \ \ \ \f[I]\f[CI]FIELDASSIGNMENTS\f[I]\f[R]...
|
the CSV file; eg double quotes are removed, and the separator character
|
||||||
|
becomes comma.
|
||||||
.PP
|
.PP
|
||||||
\f[C]if\f[R]
|
After the patterns, there should be one or more rules to apply, all
|
||||||
.PD 0
|
indented by at least one space.
|
||||||
.P
|
Three kinds of rule are allowed in conditional blocks:
|
||||||
.PD
|
.IP \[bu] 2
|
||||||
\f[I]\f[CI]PATTERN\f[I]\f[R]
|
field assignments (to set a field\[aq]s value)
|
||||||
.PD 0
|
.IP \[bu] 2
|
||||||
.P
|
skip (to skip the matched CSV record)
|
||||||
.PD
|
.IP \[bu] 2
|
||||||
\f[I]\f[CI]PATTERN\f[I]\f[R]...
|
end (to skip all remaining CSV records).
|
||||||
.PD 0
|
|
||||||
.P
|
|
||||||
.PD
|
|
||||||
\ \ \ \ \f[I]\f[CI]FIELDASSIGNMENTS\f[I]\f[R]...
|
|
||||||
.PP
|
.PP
|
||||||
This applies one or more field assignments, only to those CSV records
|
|
||||||
matched by one of the PATTERNs.
|
|
||||||
The patterns are case-insensitive regular expressions which match
|
|
||||||
anywhere within the whole CSV record (it\[aq]s not yet possible to match
|
|
||||||
within a specific field).
|
|
||||||
When there are multiple patterns they can be written on separate lines,
|
|
||||||
unindented.
|
|
||||||
The field assignments are on separate lines indented by at least one
|
|
||||||
space.
|
|
||||||
Examples:
|
Examples:
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
@ -242,112 +271,319 @@ banking thru software
|
|||||||
comment XXX deductible ? check it
|
comment XXX deductible ? check it
|
||||||
\f[R]
|
\f[R]
|
||||||
.fi
|
.fi
|
||||||
.SS include
|
.SS \f[C]end\f[R]
|
||||||
.PP
|
.PP
|
||||||
\f[C]include\f[R]\f[I]\f[CI]RULESFILE\f[I]\f[R]
|
As mentioned above, this rule can be used inside conditional blocks
|
||||||
.PP
|
(only) to cause hledger to stop reading CSV records and proceed with
|
||||||
Include another rules file at this point.
|
command execution.
|
||||||
\f[C]RULESFILE\f[R] is either an absolute file path or a path relative
|
|
||||||
to the current file\[aq]s directory.
|
|
||||||
Eg:
|
Eg:
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
# rules reused with several CSV files
|
# ignore everything following the first empty record
|
||||||
include common.rules
|
if ,,,,
|
||||||
|
end
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.SS \f[C]include\f[R]
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
include RULESFILE
|
||||||
\f[R]
|
\f[R]
|
||||||
.fi
|
.fi
|
||||||
.SS newest-first
|
|
||||||
.PP
|
.PP
|
||||||
\f[C]newest-first\f[R]
|
Include another CSV rules file at this point, as if it were written
|
||||||
|
inline.
|
||||||
|
\f[C]RULESFILE\f[R] is an absolute file path or a path relative to the
|
||||||
|
current file\[aq]s directory.
|
||||||
.PP
|
.PP
|
||||||
Consider adding this rule if all of the following are true: you might be
|
This can be useful eg for reusing common rules in several rules files:
|
||||||
processing just one day of data, your CSV records are in reverse
|
.IP
|
||||||
chronological order (newest first), and you care about preserving the
|
.nf
|
||||||
order of same-day transactions.
|
\f[C]
|
||||||
It usually isn\[aq]t needed, because hledger autodetects the CSV order,
|
# someaccount.csv.rules
|
||||||
but when all CSV records have the same date it will assume they are
|
|
||||||
oldest first.
|
## someaccount-specific rules
|
||||||
.SH CSV TIPS
|
fields date,description,amount
|
||||||
.SS CSV ordering
|
account1 some:account
|
||||||
|
account2 some:misc
|
||||||
|
|
||||||
|
## common rules
|
||||||
|
include categorisation.rules
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.SS \f[C]newest-first\f[R]
|
||||||
.PP
|
.PP
|
||||||
The generated journal entries will be sorted by date.
|
hledger always sorts the generated transactions by date.
|
||||||
The order of same-day entries will be preserved (except in the special
|
Transactions on the same date should appear in the same order as their
|
||||||
case where you might need \f[C]newest-first\f[R], see above).
|
CSV records, as hledger can usually auto-detect whether the CSV\[aq]s
|
||||||
.SS CSV accounts
|
normal order is oldest first or newest first.
|
||||||
.PP
|
But if all of the following are true:
|
||||||
Each journal entry will have two postings, to \f[C]account1\f[R] and
|
|
||||||
\f[C]account2\f[R] respectively.
|
|
||||||
It\[aq]s not yet possible to generate entries with more than two
|
|
||||||
postings.
|
|
||||||
It\[aq]s conventional and recommended to use \f[C]account1\f[R] for the
|
|
||||||
account whose CSV we are reading.
|
|
||||||
.SS CSV amounts
|
|
||||||
.PP
|
|
||||||
A transaction amount must be set, in one of these ways:
|
|
||||||
.IP \[bu] 2
|
.IP \[bu] 2
|
||||||
with an \f[C]amount\f[R] field assignment, which sets the first
|
the CSV might sometimes contain just one day of data (all records having
|
||||||
posting\[aq]s amount
|
the same date)
|
||||||
.IP \[bu] 2
|
.IP \[bu] 2
|
||||||
(When the CSV has debit and credit amounts in separate fields:)
|
the CSV records are normally in reverse chronological order (newest
|
||||||
.PD 0
|
first)
|
||||||
.P
|
|
||||||
.PD
|
|
||||||
with field assignments for the \f[C]amount-in\f[R] and
|
|
||||||
\f[C]amount-out\f[R] pseudo fields (both of them).
|
|
||||||
Whichever one has a value will be used, with appropriate sign.
|
|
||||||
If both contain a value, it might not work so well.
|
|
||||||
.IP \[bu] 2
|
.IP \[bu] 2
|
||||||
or implicitly by means of a balance assignment (see below).
|
and you care about preserving the order of same-day transactions
|
||||||
|
.PP
|
||||||
|
you should add the \f[C]newest-first\f[R] rule as a hint.
|
||||||
|
Eg:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
# tell hledger explicitly that the CSV is normally newest-first
|
||||||
|
newest-first
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.SH EXAMPLES
|
||||||
|
.PP
|
||||||
|
A more complete example, generating three-posting transactions:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
# hledger CSV rules for amazon.com order history
|
||||||
|
|
||||||
|
# sample:
|
||||||
|
# \[dq]Date\[dq],\[dq]Type\[dq],\[dq]To/From\[dq],\[dq]Name\[dq],\[dq]Status\[dq],\[dq]Amount\[dq],\[dq]Fees\[dq],\[dq]Transaction ID\[dq]
|
||||||
|
# \[dq]Jul 29, 2012\[dq],\[dq]Payment\[dq],\[dq]To\[dq],\[dq]Adapteva, Inc.\[dq],\[dq]Completed\[dq],\[dq]$25.00\[dq],\[dq]$0.00\[dq],\[dq]17LA58JSK6PRD4HDGLNJQPI1PB9N8DKPVHL\[dq]
|
||||||
|
|
||||||
|
# skip one header line
|
||||||
|
skip 1
|
||||||
|
|
||||||
|
# name the csv fields (and assign the transaction\[aq]s date, amount and code)
|
||||||
|
fields date, _, toorfrom, name, amzstatus, amount1, fees, code
|
||||||
|
|
||||||
|
# how to parse the date
|
||||||
|
date-format %b %-d, %Y
|
||||||
|
|
||||||
|
# combine two fields to make the description
|
||||||
|
description %toorfrom %name
|
||||||
|
|
||||||
|
# save these fields as tags
|
||||||
|
comment status:%amzstatus
|
||||||
|
|
||||||
|
# set the base account for all transactions
|
||||||
|
account1 assets:amazon
|
||||||
|
|
||||||
|
# flip the sign on the amount
|
||||||
|
amount -%amount
|
||||||
|
|
||||||
|
# Put fees in a separate posting
|
||||||
|
amount3 %fees
|
||||||
|
comment3 fees
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
For more examples, see Convert CSV files.
|
||||||
|
.SH TIPS
|
||||||
|
.SS Reading multiple CSV files
|
||||||
|
.PP
|
||||||
|
You can read multiple CSV files at once using multiple \f[C]-f\f[R]
|
||||||
|
arguments on the command line.
|
||||||
|
hledger will look for a correspondingly-named rules file for each CSV
|
||||||
|
file.
|
||||||
|
If you use the \f[C]--rules-file\f[R] option, that rules file will be
|
||||||
|
used for all the CSV files.
|
||||||
|
.SS Deduplicating, importing
|
||||||
|
.PP
|
||||||
|
When you download a CSV file repeatedly, eg to get your latest bank
|
||||||
|
transactions, the new file may contain some of the same records as the
|
||||||
|
old one.
|
||||||
|
The print --new command is one simple way to detect just the new
|
||||||
|
transactions.
|
||||||
|
Or better still, the import command appends those new transactions to
|
||||||
|
your main journal.
|
||||||
|
This is the easiest way to import CSV data.
|
||||||
|
Eg, after downloading your latest CSV files:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$ hledger import *.csv [--dry]
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.SS Other import methods
|
||||||
|
.PP
|
||||||
|
A number of other tools and workflows, hledger-specific and otherwise,
|
||||||
|
exist for converting, deduplicating, classifying and managing CSV data.
|
||||||
|
See:
|
||||||
|
.IP \[bu] 2
|
||||||
|
https://hledger.org -> sidebar -> real world setups
|
||||||
|
.IP \[bu] 2
|
||||||
|
https://plaintextaccounting.org -> data import/conversion
|
||||||
|
.SS Valid CSV
|
||||||
|
.PP
|
||||||
|
hledger accepts CSV conforming to RFC 4180.
|
||||||
|
Some things to note when values are enclosed in quotes:
|
||||||
|
.IP \[bu] 2
|
||||||
|
you must use double quotes (not single quotes)
|
||||||
|
.IP \[bu] 2
|
||||||
|
spaces outside the quotes are not allowed
|
||||||
|
.SS Other separator characters
|
||||||
|
.PP
|
||||||
|
With the \f[C]--separator \[aq]CHAR\[aq]\f[R] option, hledger will
|
||||||
|
expect the separator to be CHAR instead of a comma.
|
||||||
|
Ie it will read other \[dq]Character Separated Values\[dq] formats, such
|
||||||
|
as TSV (Tab Separated Values).
|
||||||
|
Note: on the command line, use a real tab character in quotes, not Eg:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$ hledger -f foo.tsv --separator \[aq] \[aq] print
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
(Experimental.)
|
||||||
|
.SS Setting amounts
|
||||||
|
.PP
|
||||||
|
A posting amount can be set in one of these ways:
|
||||||
|
.IP \[bu] 2
|
||||||
|
by assigning (with a fields list or field assigment) to
|
||||||
|
\f[C]amountN\f[R] (posting N\[aq]s amount) or \f[C]amount\f[R] (posting
|
||||||
|
1\[aq]s amount)
|
||||||
|
.IP \[bu] 2
|
||||||
|
by assigning to \f[C]amountN-in\f[R] and \f[C]amountN-out\f[R] (or
|
||||||
|
\f[C]amount-in\f[R] and \f[C]amount-out\f[R]).
|
||||||
|
For each CSV record, whichever of these has a non-zero value will be
|
||||||
|
used, with appropriate sign.
|
||||||
|
If both contain a non-zero value, this may not work.
|
||||||
|
.IP \[bu] 2
|
||||||
|
by assigning to \f[C]balanceN\f[R] (or \f[C]balance\f[R]) instead of the
|
||||||
|
above, setting the amount indirectly via a balance assignment.
|
||||||
.PP
|
.PP
|
||||||
There is some special handling for sign in amounts:
|
There is some special handling for sign in amounts:
|
||||||
.IP \[bu] 2
|
.IP \[bu] 2
|
||||||
If an amount value is parenthesised, it will be de-parenthesised and
|
If an amount value is parenthesised, it will be de-parenthesised and
|
||||||
sign-flipped.
|
sign-flipped.
|
||||||
.IP \[bu] 2
|
.IP \[bu] 2
|
||||||
If an amount value begins with a double minus sign, those will cancel
|
If an amount value begins with a double minus sign, those cancel out and
|
||||||
out and be removed.
|
are removed.
|
||||||
.PP
|
.PP
|
||||||
If the currency/commodity symbol is provided as a separate CSV field,
|
If the currency/commodity symbol is provided as a separate CSV field,
|
||||||
assign it to the \f[C]currency\f[R] pseudo field; the symbol will be
|
you can assign it to \f[C]currency\f[R] (affects all posting amounts) or
|
||||||
prepended to the amount (TODO: when there is an amount).
|
\f[C]currencyN\f[R] (affects just posting N\[aq]s amount).
|
||||||
Or, you can use an \f[C]amount\f[R] field assignment for more control,
|
The symbol will be prepended to the amount.
|
||||||
eg:
|
Or for more control, you can set both currency symbol and amount with a
|
||||||
|
field assignment, eg:
|
||||||
.IP
|
.IP
|
||||||
.nf
|
.nf
|
||||||
\f[C]
|
\f[C]
|
||||||
fields date,description,currency,amount
|
fields date,description,currency,amount
|
||||||
|
# add currency symbol on the right:
|
||||||
amount %amount %currency
|
amount %amount %currency
|
||||||
\f[R]
|
\f[R]
|
||||||
.fi
|
.fi
|
||||||
.SS CSV balance assertions/assignments
|
.SS Referencing other fields
|
||||||
.PP
|
.PP
|
||||||
If the CSV includes a running balance, you can assign that to one of the
|
In field assignments, you can interpolate only CSV fields, not hledger
|
||||||
pseudo fields \f[C]balance\f[R] (or \f[C]balance1\f[R]) or
|
fields.
|
||||||
\f[C]balance2\f[R].
|
In the example below, there\[aq]s both a CSV field and a hledger field
|
||||||
This will generate a balance assertion (or if the amount is left empty,
|
named amount1, but %amount1 always means the CSV field, not the hledger
|
||||||
a balance assignment), on the first or second posting, whenever the
|
field:
|
||||||
running balance field is non-empty.
|
.IP
|
||||||
(TODO: #1000)
|
.nf
|
||||||
.SS Reading multiple CSV files
|
\f[C]
|
||||||
|
# Name the third CSV field \[dq]amount1\[dq]
|
||||||
|
fields date,description,amount1
|
||||||
|
|
||||||
|
# Set hledger\[aq]s amount1 to the CSV amount1 field followed by USD
|
||||||
|
amount1 %amount1 USD
|
||||||
|
|
||||||
|
# Set comment to the CSV amount1 (not the amount1 assigned above)
|
||||||
|
comment %amount1
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
.PP
|
.PP
|
||||||
You can read multiple CSV files at once using multiple \f[C]-f\f[R]
|
Here, since there\[aq]s no CSV amount1 field, %amount1 will produce a
|
||||||
arguments on the command line, and hledger will look for a
|
literal \[dq]amount1\[dq]:
|
||||||
correspondingly-named rules file for each.
|
.IP
|
||||||
Note if you use the \f[C]--rules-file\f[R] option, this one rules file
|
.nf
|
||||||
will be used for all the CSV files being read.
|
\f[C]
|
||||||
.SS Valid CSV
|
fields date,description,csvamount
|
||||||
|
amount1 %csvamount USD
|
||||||
|
# Can\[aq]t interpolate amount1 here
|
||||||
|
comment %amount1
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
.PP
|
.PP
|
||||||
hledger follows RFC 4180, with the addition of a customisable separator
|
When there are multiple field assignments to the same hledger field,
|
||||||
character.
|
only the last one takes effect.
|
||||||
|
Here, comment\[aq]s value will be be B, or C if \[dq]something\[dq] is
|
||||||
|
matched, but never A:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
comment A
|
||||||
|
comment B
|
||||||
|
if something
|
||||||
|
comment C
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.SS How CSV rules are evaluated
|
||||||
.PP
|
.PP
|
||||||
Some things to note:
|
Here\[aq]s how to think of CSV rules being evaluated (if you really need
|
||||||
.PP
|
to).
|
||||||
When quoting fields,
|
First,
|
||||||
.IP \[bu] 2
|
.IP \[bu] 2
|
||||||
you must use double quotes, not single quotes
|
include - all includes are inlined, from top to bottom, depth first.
|
||||||
|
(At each include point the file is inlined and scanned for further
|
||||||
|
includes, before proceeding.)
|
||||||
|
.PP
|
||||||
|
Then \[dq]global\[dq] rules are evaluated, top to bottom.
|
||||||
|
If a rule is repeated, the last one wins:
|
||||||
.IP \[bu] 2
|
.IP \[bu] 2
|
||||||
spaces outside the quotes are not allowed.
|
skip (at top level)
|
||||||
|
.IP \[bu] 2
|
||||||
|
date-format
|
||||||
|
.IP \[bu] 2
|
||||||
|
newest-first
|
||||||
|
.IP \[bu] 2
|
||||||
|
fields - names the CSV fields, optionally sets up initial assignments to
|
||||||
|
hledger fields
|
||||||
|
.PP
|
||||||
|
Then for each CSV record in turn:
|
||||||
|
.IP \[bu] 2
|
||||||
|
test all \f[C]if\f[R] blocks.
|
||||||
|
If any of them contain a \f[C]end\f[R] rule, skip all remaining CSV
|
||||||
|
records.
|
||||||
|
Otherwise if any of them contain a \f[C]skip\f[R] rule, skip that many
|
||||||
|
CSV records.
|
||||||
|
If there are multiple matched skip rules, the first one wins.
|
||||||
|
.IP \[bu] 2
|
||||||
|
collect all field assignments at top level and in matched if blocks.
|
||||||
|
When there are multiple assignments for a field, keep only the last one.
|
||||||
|
.IP \[bu] 2
|
||||||
|
compute a value for each hledger field - either the one that was
|
||||||
|
assigned to it (and interpolate the %CSVFIELDNAME references), or a
|
||||||
|
default
|
||||||
|
.IP \[bu] 2
|
||||||
|
generate a synthetic hledger transaction from these values, which
|
||||||
|
becomes part of the input to the hledger command that has been selected
|
||||||
|
.SS Valid transactions
|
||||||
|
.PP
|
||||||
|
hledger currently does not post-process and validate transactions
|
||||||
|
generated from CSV as thoroughly as transactions read from a journal
|
||||||
|
file.
|
||||||
|
This means that if your rules are wrong, you can generate invalid
|
||||||
|
transactions.
|
||||||
|
Or, amounts may not be displayed with a canonical display style.
|
||||||
|
.PP
|
||||||
|
So when setting up or adjusting CSV rules, you should check your results
|
||||||
|
visually with the print command.
|
||||||
|
You can pipe print\[aq]s output through hledger once more to validate
|
||||||
|
and canonicalise fully.
|
||||||
|
Eg:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$ hledger -f some.csv print | hledger -f- print -I
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
(The -I/--ignore-assertions flag disables balance assertion checks,
|
||||||
|
usually needed when re-parsing print output.)
|
||||||
|
|
||||||
|
|
||||||
.SH "REPORTING BUGS"
|
.SH "REPORTING BUGS"
|
||||||
|
|||||||
@ -14,8 +14,8 @@ transaction. (To learn about _writing_ CSV, see CSV output.)
|
|||||||
rules. These do several things:
|
rules. These do several things:
|
||||||
|
|
||||||
* they describe the layout and format of the CSV data
|
* they describe the layout and format of the CSV data
|
||||||
* they can customize the generated journal entries using a simple
|
* they can customize the generated journal entries (transactions)
|
||||||
templating language
|
using a simple templating language
|
||||||
* they can add refinements based on patterns in the CSV data, eg
|
* they can add refinements based on patterns in the CSV data, eg
|
||||||
categorizing transactions with more detailed account names.
|
categorizing transactions with more detailed account names.
|
||||||
|
|
||||||
@ -33,93 +33,164 @@ fields date, _, _, amount
|
|||||||
date-format %d/%m/%Y
|
date-format %d/%m/%Y
|
||||||
skip 1
|
skip 1
|
||||||
|
|
||||||
A more complete example:
|
More examples in the EXAMPLES section below.
|
||||||
|
|
||||||
# hledger CSV rules for amazon.com order history
|
|
||||||
|
|
||||||
# sample:
|
|
||||||
# "Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID"
|
|
||||||
# "Jul 29, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$0.00","17LA58JSK6PRD4HDGLNJQPI1PB9N8DKPVHL"
|
|
||||||
|
|
||||||
# skip one header line
|
|
||||||
skip 1
|
|
||||||
|
|
||||||
# name the csv fields (and assign the transaction's date, amount and code)
|
|
||||||
fields date, _, toorfrom, name, amzstatus, amount, fees, code
|
|
||||||
|
|
||||||
# how to parse the date
|
|
||||||
date-format %b %-d, %Y
|
|
||||||
|
|
||||||
# combine two fields to make the description
|
|
||||||
description %toorfrom %name
|
|
||||||
|
|
||||||
# save these fields as tags
|
|
||||||
comment status:%amzstatus, fees:%fees
|
|
||||||
|
|
||||||
# set the base account for all transactions
|
|
||||||
account1 assets:amazon
|
|
||||||
|
|
||||||
# flip the sign on the amount
|
|
||||||
amount -%amount
|
|
||||||
|
|
||||||
For more examples, see Convert CSV files.
|
|
||||||
|
|
||||||
* Menu:
|
* Menu:
|
||||||
|
|
||||||
* CSV RULES::
|
* CSV RULES::
|
||||||
* CSV TIPS::
|
* EXAMPLES::
|
||||||
|
* TIPS::
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: CSV RULES, Next: CSV TIPS, Prev: Top, Up: Top
|
File: hledger_csv.info, Node: CSV RULES, Next: EXAMPLES, Prev: Top, Up: Top
|
||||||
|
|
||||||
1 CSV RULES
|
1 CSV RULES
|
||||||
***********
|
***********
|
||||||
|
|
||||||
The following seven kinds of rule can appear in the rules file, in any
|
The following kinds of rule can appear in the rules file, in any order
|
||||||
order. Blank lines and lines beginning with '#' or ';' are ignored.
|
(except for 'end' which can appear only inside a conditional block).
|
||||||
|
Blank lines and lines beginning with '#' or ';' are ignored.
|
||||||
|
|
||||||
* Menu:
|
* Menu:
|
||||||
|
|
||||||
* skip::
|
* skip::
|
||||||
* date-format::
|
* fields::
|
||||||
* field list::
|
|
||||||
* field assignment::
|
* field assignment::
|
||||||
* conditional block::
|
* date-format::
|
||||||
|
* if::
|
||||||
|
* end::
|
||||||
* include::
|
* include::
|
||||||
* newest-first::
|
* newest-first::
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: skip, Next: date-format, Up: CSV RULES
|
File: hledger_csv.info, Node: skip, Next: fields, Up: CSV RULES
|
||||||
|
|
||||||
1.1 skip
|
1.1 'skip'
|
||||||
========
|
==========
|
||||||
|
|
||||||
'skip'_'N'_
|
skip N
|
||||||
|
|
||||||
Skip this many non-empty lines preceding the CSV data. (Empty/blank
|
The word "skip" followed by a number (or no number, meaning 1) tells
|
||||||
lines are skipped automatically.) You'll need this whenever your CSV
|
hledger to ignore this many non-empty lines preceding the CSV data.
|
||||||
data contains header lines. Eg:
|
(Empty/blank lines are skipped automatically.) You'll need this
|
||||||
|
whenever your CSV data contains header lines.
|
||||||
|
|
||||||
# ignore the first CSV line
|
It also has a second purpose: it can be used to ignore certain CSV
|
||||||
skip 1
|
records, see conditional blocks below.
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: date-format, Next: field list, Prev: skip, Up: CSV RULES
|
File: hledger_csv.info, Node: fields, Next: field assignment, Prev: skip, Up: CSV RULES
|
||||||
|
|
||||||
1.2 date-format
|
1.2 'fields'
|
||||||
===============
|
============
|
||||||
|
|
||||||
'date-format'_'DATEFMT'_
|
fields FIELDNAME1, FIELDNAME2, ...
|
||||||
|
|
||||||
When your CSV date fields are not formatted like 'YYYY/MM/DD' (or
|
A fields list ("fields" followed by one or more comma-separated field
|
||||||
'YYYY-MM-DD' or 'YYYY.MM.DD'), you'll need to specify the format.
|
names) is the quick way to assign CSV field values to hledger fields.
|
||||||
DATEFMT is a strptime-like date parsing pattern, which must parse the
|
It (a) names the CSV fields, in order (names may not contain whitespace;
|
||||||
date field values completely. Examples:
|
fields you don't care about can be left unnamed), and (b) assigns them
|
||||||
|
to hledger fields if you use standard hledger field names. Here's an
|
||||||
|
example:
|
||||||
|
|
||||||
|
# use the 1st, 2nd and 4th CSV fields as the transaction's date, description and amount,
|
||||||
|
# ignore the 3rd, 5th and 6th fields,
|
||||||
|
# and name the 7th and 8th fields for later reference:
|
||||||
|
# 1 2 3 4 5 6 7 8
|
||||||
|
|
||||||
|
fields date, description, , amount1, , , somefield, anotherfield
|
||||||
|
|
||||||
|
Here are the standard hledger field names:
|
||||||
|
|
||||||
|
* Menu:
|
||||||
|
|
||||||
|
* Transaction fields::
|
||||||
|
* Posting fields::
|
||||||
|
|
||||||
|
|
||||||
|
File: hledger_csv.info, Node: Transaction fields, Next: Posting fields, Up: fields
|
||||||
|
|
||||||
|
1.2.1 Transaction fields
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
'date', 'date2', 'status', 'code', 'description', 'comment' can be used
|
||||||
|
to form the transaction's first line. Only 'date' is required. (See
|
||||||
|
also date-format below.)
|
||||||
|
|
||||||
|
|
||||||
|
File: hledger_csv.info, Node: Posting fields, Prev: Transaction fields, Up: fields
|
||||||
|
|
||||||
|
1.2.2 Posting fields
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
'accountN', where N is 1 to 9, sets the Nth posting's account name.
|
||||||
|
Most often there are two postings, so you'll want to set 'account1' and
|
||||||
|
'account2'.
|
||||||
|
|
||||||
|
A number of field/pseudo-field names are available for setting
|
||||||
|
posting amounts:
|
||||||
|
|
||||||
|
* 'amountN' sets posting N's amount
|
||||||
|
* 'amountN-in' and 'amountN-out' can be used instead, if the CSV has
|
||||||
|
separate fields for debits and credits
|
||||||
|
* 'currencyN' sets a currency symbol to be left-prefixed to the
|
||||||
|
amount, useful if the CSV provides that as a separate field
|
||||||
|
* 'balanceN' sets a (separate) balance assertion amount (or when no
|
||||||
|
posting amount is set, a balance assignment)
|
||||||
|
|
||||||
|
If you write these with no number ('amount', 'amount-in',
|
||||||
|
'amount-out', 'currency', 'balance'), it means posting 1. Also, if you
|
||||||
|
set an amount for posting 1 only, a second posting that balances the
|
||||||
|
transaction will be generated automatically. This helps support CSV
|
||||||
|
rules created before hledger 1.16.
|
||||||
|
|
||||||
|
Finally, 'commentN' sets a comment on the Nth posting. Comments can
|
||||||
|
of course contain tags.
|
||||||
|
|
||||||
|
|
||||||
|
File: hledger_csv.info, Node: field assignment, Next: date-format, Prev: fields, Up: CSV RULES
|
||||||
|
|
||||||
|
1.3 '(field assignment)'
|
||||||
|
========================
|
||||||
|
|
||||||
|
HLEDGERFIELDNAME FIELDVALUE
|
||||||
|
|
||||||
|
Instead of or in addition to a fields list, you can assign a value to
|
||||||
|
a hledger field by writing its name (any of the standard names above)
|
||||||
|
followed by a text value. The value may contain interpolated CSV
|
||||||
|
fields, referenced by their 1-based position in the CSV record ('%N'),
|
||||||
|
or by the name they were given in the fields list ('%CSVFIELDNAME').
|
||||||
|
Eg:
|
||||||
|
|
||||||
|
# set the amount to the 4th CSV field, with " USD" appended
|
||||||
|
amount %4 USD
|
||||||
|
|
||||||
|
# combine three fields to make a comment, containing note: and date: tags
|
||||||
|
comment note: %somefield - %anotherfield, date: %1
|
||||||
|
|
||||||
|
Interpolation strips any outer whitespace, so a CSV value like '" 1
|
||||||
|
"' becomes '1' when interpolated (#1051). Note you can only interpolate
|
||||||
|
CSV fields, not the hledger fields being assigned to; for more on this,
|
||||||
|
see TIPS.
|
||||||
|
|
||||||
|
|
||||||
|
File: hledger_csv.info, Node: date-format, Next: if, Prev: field assignment, Up: CSV RULES
|
||||||
|
|
||||||
|
1.4 'date-format'
|
||||||
|
=================
|
||||||
|
|
||||||
|
date-format DATEFMT
|
||||||
|
|
||||||
|
This is a helper for the 'date' (and 'date2') fields. If your CSV
|
||||||
|
dates are not formatted like 'YYYY-MM-DD', 'YYYY/MM/DD' or 'YYYY.MM.DD',
|
||||||
|
you'll need to specify the format by writing "date-format" followed by a
|
||||||
|
strptime-like date parsing pattern, which must parse the date field
|
||||||
|
values completely. Examples:
|
||||||
|
|
||||||
# for dates like "11/06/2013":
|
# for dates like "11/06/2013":
|
||||||
date-format %m/%d/%Y
|
date-format %m/%d/%Y
|
||||||
|
|
||||||
# for dates like "6/11/2013" (note the - to make leading zeros optional):
|
# for dates like "6/11/2013". The - allows leading zeros to be optional.
|
||||||
date-format %-d/%-m/%Y
|
date-format %-d/%-m/%Y
|
||||||
|
|
||||||
# for dates like "2013-Nov-06":
|
# for dates like "2013-Nov-06":
|
||||||
@ -129,73 +200,43 @@ date-format %Y-%h-%d
|
|||||||
date-format %-m/%-d/%Y %l:%M %p
|
date-format %-m/%-d/%Y %l:%M %p
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: field list, Next: field assignment, Prev: date-format, Up: CSV RULES
|
File: hledger_csv.info, Node: if, Next: end, Prev: date-format, Up: CSV RULES
|
||||||
|
|
||||||
1.3 field list
|
1.5 'if'
|
||||||
==============
|
========
|
||||||
|
|
||||||
'fields'_'FIELDNAME1'_, _'FIELDNAME2'_...
|
if PATTERN
|
||||||
|
RULE
|
||||||
|
|
||||||
This (a) names the CSV fields, in order (names may not contain
|
if
|
||||||
whitespace; uninteresting names may be left blank), and (b) assigns them
|
PATTERN
|
||||||
to journal entry fields if you use any of these standard field names:
|
PATTERN
|
||||||
'date', 'date2', 'status', 'code', 'description', 'comment', 'account1',
|
PATTERN
|
||||||
'account2', 'amount', 'amount-in', 'amount-out', 'currency', 'balance',
|
RULE
|
||||||
'balance1', 'balance2'. Eg:
|
RULE
|
||||||
|
|
||||||
# use the 1st, 2nd and 4th CSV fields as the entry's date, description and amount,
|
Conditional blocks apply one or more rules to CSV records which are
|
||||||
# and give the 7th and 8th fields meaningful names for later reference:
|
matched by any of the PATTERNs. This allows transactions to be
|
||||||
#
|
customised or categorised based on patterns in the data.
|
||||||
# CSV field:
|
|
||||||
# 1 2 3 4 5 6 7 8
|
|
||||||
# entry field:
|
|
||||||
fields date, description, , amount, , , somefield, anotherfield
|
|
||||||
|
|
||||||
|
A single pattern can be written on the same line as the "if"; or
|
||||||
File: hledger_csv.info, Node: field assignment, Next: conditional block, Prev: field list, Up: CSV RULES
|
multiple patterns can be written on the following lines, non-indented.
|
||||||
|
|
||||||
1.4 field assignment
|
Patterns are case-insensitive regular expressions which try to match
|
||||||
====================
|
any part of the whole CSV record. It's not yet possible to match within
|
||||||
|
a specific field. Note the CSV record they see is close but not
|
||||||
|
identical to the one in the CSV file; eg double quotes are removed, and
|
||||||
|
the separator character becomes comma.
|
||||||
|
|
||||||
_'ENTRYFIELDNAME'_ _'FIELDVALUE'_
|
After the patterns, there should be one or more rules to apply, all
|
||||||
|
indented by at least one space. Three kinds of rule are allowed in
|
||||||
|
conditional blocks:
|
||||||
|
|
||||||
This sets a journal entry field (one of the standard names above) to
|
* field assignments (to set a field's value)
|
||||||
the given text value, which can include CSV field values interpolated by
|
* skip (to skip the matched CSV record)
|
||||||
name ('%CSVFIELDNAME') or 1-based position ('%N'). Eg:
|
* end (to skip all remaining CSV records).
|
||||||
|
|
||||||
# set the amount to the 4th CSV field with "USD " prepended
|
Examples:
|
||||||
amount USD %4
|
|
||||||
|
|
||||||
# combine three fields to make a comment (containing two tags)
|
|
||||||
comment note: %somefield - %anotherfield, date: %1
|
|
||||||
|
|
||||||
Field assignments can be used instead of or in addition to a field
|
|
||||||
list.
|
|
||||||
|
|
||||||
Note, interpolation strips any outer whitespace, so a CSV value like
|
|
||||||
'" 1 "' becomes '1' when interpolated (#1051).
|
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: conditional block, Next: include, Prev: field assignment, Up: CSV RULES
|
|
||||||
|
|
||||||
1.5 conditional block
|
|
||||||
=====================
|
|
||||||
|
|
||||||
'if' _'PATTERN'_
|
|
||||||
_'FIELDASSIGNMENTS'_...
|
|
||||||
|
|
||||||
'if'
|
|
||||||
_'PATTERN'_
|
|
||||||
_'PATTERN'_...
|
|
||||||
_'FIELDASSIGNMENTS'_...
|
|
||||||
|
|
||||||
This applies one or more field assignments, only to those CSV records
|
|
||||||
matched by one of the PATTERNs. The patterns are case-insensitive
|
|
||||||
regular expressions which match anywhere within the whole CSV record
|
|
||||||
(it's not yet possible to match within a specific field). When there
|
|
||||||
are multiple patterns they can be written on separate lines, unindented.
|
|
||||||
The field assignments are on separate lines indented by at least one
|
|
||||||
space. Examples:
|
|
||||||
|
|
||||||
# if the CSV record contains "groceries", set account2 to "expenses:groceries"
|
# if the CSV record contains "groceries", set account2 to "expenses:groceries"
|
||||||
if groceries
|
if groceries
|
||||||
@ -210,176 +251,369 @@ banking thru software
|
|||||||
comment XXX deductible ? check it
|
comment XXX deductible ? check it
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: include, Next: newest-first, Prev: conditional block, Up: CSV RULES
|
File: hledger_csv.info, Node: end, Next: include, Prev: if, Up: CSV RULES
|
||||||
|
|
||||||
1.6 include
|
1.6 'end'
|
||||||
===========
|
=========
|
||||||
|
|
||||||
'include'_'RULESFILE'_
|
As mentioned above, this rule can be used inside conditional blocks
|
||||||
|
(only) to cause hledger to stop reading CSV records and proceed with
|
||||||
|
command execution. Eg:
|
||||||
|
|
||||||
Include another rules file at this point. 'RULESFILE' is either an
|
# ignore everything following the first empty record
|
||||||
absolute file path or a path relative to the current file's directory.
|
if ,,,,
|
||||||
Eg:
|
end
|
||||||
|
|
||||||
# rules reused with several CSV files
|
|
||||||
include common.rules
|
File: hledger_csv.info, Node: include, Next: newest-first, Prev: end, Up: CSV RULES
|
||||||
|
|
||||||
|
1.7 'include'
|
||||||
|
=============
|
||||||
|
|
||||||
|
include RULESFILE
|
||||||
|
|
||||||
|
Include another CSV rules file at this point, as if it were written
|
||||||
|
inline. 'RULESFILE' is an absolute file path or a path relative to the
|
||||||
|
current file's directory.
|
||||||
|
|
||||||
|
This can be useful eg for reusing common rules in several rules
|
||||||
|
files:
|
||||||
|
|
||||||
|
# someaccount.csv.rules
|
||||||
|
|
||||||
|
## someaccount-specific rules
|
||||||
|
fields date,description,amount
|
||||||
|
account1 some:account
|
||||||
|
account2 some:misc
|
||||||
|
|
||||||
|
## common rules
|
||||||
|
include categorisation.rules
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: newest-first, Prev: include, Up: CSV RULES
|
File: hledger_csv.info, Node: newest-first, Prev: include, Up: CSV RULES
|
||||||
|
|
||||||
1.7 newest-first
|
1.8 'newest-first'
|
||||||
================
|
==================
|
||||||
|
|
||||||
'newest-first'
|
hledger always sorts the generated transactions by date. Transactions
|
||||||
|
on the same date should appear in the same order as their CSV records,
|
||||||
|
as hledger can usually auto-detect whether the CSV's normal order is
|
||||||
|
oldest first or newest first. But if all of the following are true:
|
||||||
|
|
||||||
Consider adding this rule if all of the following are true: you might
|
* the CSV might sometimes contain just one day of data (all records
|
||||||
be processing just one day of data, your CSV records are in reverse
|
having the same date)
|
||||||
chronological order (newest first), and you care about preserving the
|
* the CSV records are normally in reverse chronological order (newest
|
||||||
order of same-day transactions. It usually isn't needed, because
|
first)
|
||||||
hledger autodetects the CSV order, but when all CSV records have the
|
* and you care about preserving the order of same-day transactions
|
||||||
same date it will assume they are oldest first.
|
|
||||||
|
you should add the 'newest-first' rule as a hint. Eg:
|
||||||
|
|
||||||
|
# tell hledger explicitly that the CSV is normally newest-first
|
||||||
|
newest-first
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: CSV TIPS, Prev: CSV RULES, Up: Top
|
File: hledger_csv.info, Node: EXAMPLES, Next: TIPS, Prev: CSV RULES, Up: Top
|
||||||
|
|
||||||
2 CSV TIPS
|
2 EXAMPLES
|
||||||
**********
|
**********
|
||||||
|
|
||||||
|
A more complete example, generating three-posting transactions:
|
||||||
|
|
||||||
|
# hledger CSV rules for amazon.com order history
|
||||||
|
|
||||||
|
# sample:
|
||||||
|
# "Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID"
|
||||||
|
# "Jul 29, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$0.00","17LA58JSK6PRD4HDGLNJQPI1PB9N8DKPVHL"
|
||||||
|
|
||||||
|
# skip one header line
|
||||||
|
skip 1
|
||||||
|
|
||||||
|
# name the csv fields (and assign the transaction's date, amount and code)
|
||||||
|
fields date, _, toorfrom, name, amzstatus, amount1, fees, code
|
||||||
|
|
||||||
|
# how to parse the date
|
||||||
|
date-format %b %-d, %Y
|
||||||
|
|
||||||
|
# combine two fields to make the description
|
||||||
|
description %toorfrom %name
|
||||||
|
|
||||||
|
# save these fields as tags
|
||||||
|
comment status:%amzstatus
|
||||||
|
|
||||||
|
# set the base account for all transactions
|
||||||
|
account1 assets:amazon
|
||||||
|
|
||||||
|
# flip the sign on the amount
|
||||||
|
amount -%amount
|
||||||
|
|
||||||
|
# Put fees in a separate posting
|
||||||
|
amount3 %fees
|
||||||
|
comment3 fees
|
||||||
|
|
||||||
|
For more examples, see Convert CSV files.
|
||||||
|
|
||||||
|
|
||||||
|
File: hledger_csv.info, Node: TIPS, Prev: EXAMPLES, Up: Top
|
||||||
|
|
||||||
|
3 TIPS
|
||||||
|
******
|
||||||
|
|
||||||
* Menu:
|
* Menu:
|
||||||
|
|
||||||
* CSV ordering::
|
|
||||||
* CSV accounts::
|
|
||||||
* CSV amounts::
|
|
||||||
* CSV balance assertions/assignments::
|
|
||||||
* Reading multiple CSV files::
|
* Reading multiple CSV files::
|
||||||
|
* Deduplicating importing::
|
||||||
|
* Other import methods::
|
||||||
* Valid CSV::
|
* Valid CSV::
|
||||||
|
* Other separator characters::
|
||||||
|
* Setting amounts::
|
||||||
|
* Referencing other fields::
|
||||||
|
* How CSV rules are evaluated::
|
||||||
|
* Valid transactions::
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: CSV ordering, Next: CSV accounts, Up: CSV TIPS
|
File: hledger_csv.info, Node: Reading multiple CSV files, Next: Deduplicating importing, Up: TIPS
|
||||||
|
|
||||||
2.1 CSV ordering
|
3.1 Reading multiple CSV files
|
||||||
================
|
==============================
|
||||||
|
|
||||||
The generated journal entries will be sorted by date. The order of
|
You can read multiple CSV files at once using multiple '-f' arguments on
|
||||||
same-day entries will be preserved (except in the special case where you
|
the command line. hledger will look for a correspondingly-named rules
|
||||||
might need 'newest-first', see above).
|
file for each CSV file. If you use the '--rules-file' option, that
|
||||||
|
rules file will be used for all the CSV files.
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: CSV accounts, Next: CSV amounts, Prev: CSV ordering, Up: CSV TIPS
|
File: hledger_csv.info, Node: Deduplicating importing, Next: Other import methods, Prev: Reading multiple CSV files, Up: TIPS
|
||||||
|
|
||||||
2.2 CSV accounts
|
3.2 Deduplicating, importing
|
||||||
================
|
============================
|
||||||
|
|
||||||
Each journal entry will have two postings, to 'account1' and 'account2'
|
When you download a CSV file repeatedly, eg to get your latest bank
|
||||||
respectively. It's not yet possible to generate entries with more than
|
transactions, the new file may contain some of the same records as the
|
||||||
two postings. It's conventional and recommended to use 'account1' for
|
old one. The print -new command is one simple way to detect just the
|
||||||
the account whose CSV we are reading.
|
new transactions. Or better still, the import command appends those new
|
||||||
|
transactions to your main journal. This is the easiest way to import
|
||||||
|
CSV data. Eg, after downloading your latest CSV files:
|
||||||
|
|
||||||
|
$ hledger import *.csv [--dry]
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: CSV amounts, Next: CSV balance assertions/assignments, Prev: CSV accounts, Up: CSV TIPS
|
File: hledger_csv.info, Node: Other import methods, Next: Valid CSV, Prev: Deduplicating importing, Up: TIPS
|
||||||
|
|
||||||
2.3 CSV amounts
|
3.3 Other import methods
|
||||||
===============
|
========================
|
||||||
|
|
||||||
A transaction amount must be set, in one of these ways:
|
A number of other tools and workflows, hledger-specific and otherwise,
|
||||||
|
exist for converting, deduplicating, classifying and managing CSV data.
|
||||||
|
See:
|
||||||
|
|
||||||
* with an 'amount' field assignment, which sets the first posting's
|
* https://hledger.org -> sidebar -> real world setups
|
||||||
amount
|
* https://plaintextaccounting.org -> data import/conversion
|
||||||
|
|
||||||
* (When the CSV has debit and credit amounts in separate fields:)
|
|
||||||
with field assignments for the 'amount-in' and 'amount-out' pseudo
|
File: hledger_csv.info, Node: Valid CSV, Next: Other separator characters, Prev: Other import methods, Up: TIPS
|
||||||
fields (both of them). Whichever one has a value will be used,
|
|
||||||
with appropriate sign. If both contain a value, it might not work
|
|
||||||
so well.
|
|
||||||
|
|
||||||
* or implicitly by means of a balance assignment (see below).
|
3.4 Valid CSV
|
||||||
|
=============
|
||||||
|
|
||||||
|
hledger accepts CSV conforming to RFC 4180. Some things to note when
|
||||||
|
values are enclosed in quotes:
|
||||||
|
|
||||||
|
* you must use double quotes (not single quotes)
|
||||||
|
* spaces outside the quotes are not allowed
|
||||||
|
|
||||||
|
|
||||||
|
File: hledger_csv.info, Node: Other separator characters, Next: Setting amounts, Prev: Valid CSV, Up: TIPS
|
||||||
|
|
||||||
|
3.5 Other separator characters
|
||||||
|
==============================
|
||||||
|
|
||||||
|
With the '--separator 'CHAR'' option, hledger will expect the separator
|
||||||
|
to be CHAR instead of a comma. Ie it will read other "Character
|
||||||
|
Separated Values" formats, such as TSV (Tab Separated Values). Note: on
|
||||||
|
the command line, use a real tab character in quotes, not
|
||||||
|
|
||||||
|
$ hledger -f foo.tsv --separator ' ' print
|
||||||
|
|
||||||
|
(Experimental.)
|
||||||
|
|
||||||
|
|
||||||
|
File: hledger_csv.info, Node: Setting amounts, Next: Referencing other fields, Prev: Other separator characters, Up: TIPS
|
||||||
|
|
||||||
|
3.6 Setting amounts
|
||||||
|
===================
|
||||||
|
|
||||||
|
A posting amount can be set in one of these ways:
|
||||||
|
|
||||||
|
* by assigning (with a fields list or field assigment) to 'amountN'
|
||||||
|
(posting N's amount) or 'amount' (posting 1's amount)
|
||||||
|
|
||||||
|
* by assigning to 'amountN-in' and 'amountN-out' (or 'amount-in' and
|
||||||
|
'amount-out'). For each CSV record, whichever of these has a
|
||||||
|
non-zero value will be used, with appropriate sign. If both
|
||||||
|
contain a non-zero value, this may not work.
|
||||||
|
|
||||||
|
* by assigning to 'balanceN' (or 'balance') instead of the above,
|
||||||
|
setting the amount indirectly via a balance assignment.
|
||||||
|
|
||||||
There is some special handling for sign in amounts:
|
There is some special handling for sign in amounts:
|
||||||
|
|
||||||
* If an amount value is parenthesised, it will be de-parenthesised
|
* If an amount value is parenthesised, it will be de-parenthesised
|
||||||
and sign-flipped.
|
and sign-flipped.
|
||||||
* If an amount value begins with a double minus sign, those will
|
* If an amount value begins with a double minus sign, those cancel
|
||||||
cancel out and be removed.
|
out and are removed.
|
||||||
|
|
||||||
If the currency/commodity symbol is provided as a separate CSV field,
|
If the currency/commodity symbol is provided as a separate CSV field,
|
||||||
assign it to the 'currency' pseudo field; the symbol will be prepended
|
you can assign it to 'currency' (affects all posting amounts) or
|
||||||
to the amount (TODO: when there is an amount). Or, you can use an
|
'currencyN' (affects just posting N's amount). The symbol will be
|
||||||
'amount' field assignment for more control, eg:
|
prepended to the amount. Or for more control, you can set both currency
|
||||||
|
symbol and amount with a field assignment, eg:
|
||||||
|
|
||||||
fields date,description,currency,amount
|
fields date,description,currency,amount
|
||||||
|
# add currency symbol on the right:
|
||||||
amount %amount %currency
|
amount %amount %currency
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: CSV balance assertions/assignments, Next: Reading multiple CSV files, Prev: CSV amounts, Up: CSV TIPS
|
File: hledger_csv.info, Node: Referencing other fields, Next: How CSV rules are evaluated, Prev: Setting amounts, Up: TIPS
|
||||||
|
|
||||||
2.4 CSV balance assertions/assignments
|
3.7 Referencing other fields
|
||||||
======================================
|
============================
|
||||||
|
|
||||||
If the CSV includes a running balance, you can assign that to one of the
|
In field assignments, you can interpolate only CSV fields, not hledger
|
||||||
pseudo fields 'balance' (or 'balance1') or 'balance2'. This will
|
fields. In the example below, there's both a CSV field and a hledger
|
||||||
generate a balance assertion (or if the amount is left empty, a balance
|
field named amount1, but %amount1 always means the CSV field, not the
|
||||||
assignment), on the first or second posting, whenever the running
|
hledger field:
|
||||||
balance field is non-empty. (TODO: #1000)
|
|
||||||
|
# Name the third CSV field "amount1"
|
||||||
|
fields date,description,amount1
|
||||||
|
|
||||||
|
# Set hledger's amount1 to the CSV amount1 field followed by USD
|
||||||
|
amount1 %amount1 USD
|
||||||
|
|
||||||
|
# Set comment to the CSV amount1 (not the amount1 assigned above)
|
||||||
|
comment %amount1
|
||||||
|
|
||||||
|
Here, since there's no CSV amount1 field, %amount1 will produce a
|
||||||
|
literal "amount1":
|
||||||
|
|
||||||
|
fields date,description,csvamount
|
||||||
|
amount1 %csvamount USD
|
||||||
|
# Can't interpolate amount1 here
|
||||||
|
comment %amount1
|
||||||
|
|
||||||
|
When there are multiple field assignments to the same hledger field,
|
||||||
|
only the last one takes effect. Here, comment's value will be be B, or
|
||||||
|
C if "something" is matched, but never A:
|
||||||
|
|
||||||
|
comment A
|
||||||
|
comment B
|
||||||
|
if something
|
||||||
|
comment C
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: Reading multiple CSV files, Next: Valid CSV, Prev: CSV balance assertions/assignments, Up: CSV TIPS
|
File: hledger_csv.info, Node: How CSV rules are evaluated, Next: Valid transactions, Prev: Referencing other fields, Up: TIPS
|
||||||
|
|
||||||
2.5 Reading multiple CSV files
|
3.8 How CSV rules are evaluated
|
||||||
==============================
|
===============================
|
||||||
|
|
||||||
You can read multiple CSV files at once using multiple '-f' arguments on
|
Here's how to think of CSV rules being evaluated (if you really need
|
||||||
the command line, and hledger will look for a correspondingly-named
|
to). First,
|
||||||
rules file for each. Note if you use the '--rules-file' option, this
|
|
||||||
one rules file will be used for all the CSV files being read.
|
* include - all includes are inlined, from top to bottom, depth
|
||||||
|
first. (At each include point the file is inlined and scanned for
|
||||||
|
further includes, before proceeding.)
|
||||||
|
|
||||||
|
Then "global" rules are evaluated, top to bottom. If a rule is
|
||||||
|
repeated, the last one wins:
|
||||||
|
|
||||||
|
* skip (at top level)
|
||||||
|
* date-format
|
||||||
|
* newest-first
|
||||||
|
* fields - names the CSV fields, optionally sets up initial
|
||||||
|
assignments to hledger fields
|
||||||
|
|
||||||
|
Then for each CSV record in turn:
|
||||||
|
|
||||||
|
* test all 'if' blocks. If any of them contain a 'end' rule, skip
|
||||||
|
all remaining CSV records. Otherwise if any of them contain a
|
||||||
|
'skip' rule, skip that many CSV records. If there are multiple
|
||||||
|
matched skip rules, the first one wins.
|
||||||
|
* collect all field assignments at top level and in matched if
|
||||||
|
blocks. When there are multiple assignments for a field, keep only
|
||||||
|
the last one.
|
||||||
|
* compute a value for each hledger field - either the one that was
|
||||||
|
assigned to it (and interpolate the %CSVFIELDNAME references), or a
|
||||||
|
default
|
||||||
|
* generate a synthetic hledger transaction from these values, which
|
||||||
|
becomes part of the input to the hledger command that has been
|
||||||
|
selected
|
||||||
|
|
||||||
|
|
||||||
File: hledger_csv.info, Node: Valid CSV, Prev: Reading multiple CSV files, Up: CSV TIPS
|
File: hledger_csv.info, Node: Valid transactions, Prev: How CSV rules are evaluated, Up: TIPS
|
||||||
|
|
||||||
2.6 Valid CSV
|
3.9 Valid transactions
|
||||||
=============
|
======================
|
||||||
|
|
||||||
hledger follows RFC 4180, with the addition of a customisable separator
|
hledger currently does not post-process and validate transactions
|
||||||
character.
|
generated from CSV as thoroughly as transactions read from a journal
|
||||||
|
file. This means that if your rules are wrong, you can generate invalid
|
||||||
|
transactions. Or, amounts may not be displayed with a canonical display
|
||||||
|
style.
|
||||||
|
|
||||||
Some things to note:
|
So when setting up or adjusting CSV rules, you should check your
|
||||||
|
results visually with the print command. You can pipe print's output
|
||||||
|
through hledger once more to validate and canonicalise fully. Eg:
|
||||||
|
|
||||||
When quoting fields,
|
$ hledger -f some.csv print | hledger -f- print -I
|
||||||
|
|
||||||
* you must use double quotes, not single quotes
|
(The -I/-ignore-assertions flag disables balance assertion checks,
|
||||||
* spaces outside the quotes are not allowed.
|
usually needed when re-parsing print output.)
|
||||||
|
|
||||||
|
|
||||||
Tag Table:
|
Tag Table:
|
||||||
Node: Top72
|
Node: Top72
|
||||||
Node: CSV RULES2167
|
Node: CSV RULES1428
|
||||||
Ref: #csv-rules2275
|
Ref: #csv-rules1536
|
||||||
Node: skip2538
|
Node: skip1849
|
||||||
Ref: #skip2632
|
Ref: #skip1942
|
||||||
Node: date-format2857
|
Node: fields2312
|
||||||
Ref: #date-format2984
|
Ref: #fields2434
|
||||||
Node: field list3534
|
Node: Transaction fields3239
|
||||||
Ref: #field-list3671
|
Ref: #transaction-fields3379
|
||||||
Node: field assignment4401
|
Node: Posting fields3547
|
||||||
Ref: #field-assignment4556
|
Ref: #posting-fields3679
|
||||||
Node: conditional block5180
|
Node: field assignment4729
|
||||||
Ref: #conditional-block5334
|
Ref: #field-assignment4882
|
||||||
Node: include6230
|
Node: date-format5693
|
||||||
Ref: #include6360
|
Ref: #date-format5828
|
||||||
Node: newest-first6591
|
Node: if6440
|
||||||
Ref: #newest-first6705
|
Ref: #if6544
|
||||||
Node: CSV TIPS7116
|
Node: end7915
|
||||||
Ref: #csv-tips7210
|
Ref: #end8017
|
||||||
Node: CSV ordering7354
|
Node: include8246
|
||||||
Ref: #csv-ordering7472
|
Ref: #include8366
|
||||||
Node: CSV accounts7653
|
Node: newest-first8804
|
||||||
Ref: #csv-accounts7791
|
Ref: #newest-first8922
|
||||||
Node: CSV amounts8045
|
Node: EXAMPLES9594
|
||||||
Ref: #csv-amounts8203
|
Ref: #examples9701
|
||||||
Node: CSV balance assertions/assignments9283
|
Node: TIPS10607
|
||||||
Ref: #csv-balance-assertionsassignments9501
|
Ref: #tips10688
|
||||||
Node: Reading multiple CSV files9822
|
Node: Reading multiple CSV files10931
|
||||||
Ref: #reading-multiple-csv-files10022
|
Ref: #reading-multiple-csv-files11098
|
||||||
Node: Valid CSV10296
|
Node: Deduplicating importing11358
|
||||||
Ref: #valid-csv10419
|
Ref: #deduplicating-importing11550
|
||||||
|
Node: Other import methods11991
|
||||||
|
Ref: #other-import-methods12158
|
||||||
|
Node: Valid CSV12428
|
||||||
|
Ref: #valid-csv12576
|
||||||
|
Node: Other separator characters12778
|
||||||
|
Ref: #other-separator-characters12955
|
||||||
|
Node: Setting amounts13289
|
||||||
|
Ref: #setting-amounts13459
|
||||||
|
Node: Referencing other fields14702
|
||||||
|
Ref: #referencing-other-fields14891
|
||||||
|
Node: How CSV rules are evaluated15788
|
||||||
|
Ref: #how-csv-rules-are-evaluated15986
|
||||||
|
Node: Valid transactions17266
|
||||||
|
Ref: #valid-transactions17413
|
||||||
|
|
||||||
End Tag Table
|
End Tag Table
|
||||||
|
|||||||
@ -16,8 +16,8 @@ DESCRIPTION
|
|||||||
|
|
||||||
o they describe the layout and format of the CSV data
|
o they describe the layout and format of the CSV data
|
||||||
|
|
||||||
o they can customize the generated journal entries using a simple tem-
|
o they can customize the generated journal entries (transactions) using
|
||||||
plating language
|
a simple templating language
|
||||||
|
|
||||||
o they can add refinements based on patterns in the CSV data, eg cate-
|
o they can add refinements based on patterns in the CSV data, eg cate-
|
||||||
gorizing transactions with more detailed account names.
|
gorizing transactions with more detailed account names.
|
||||||
@ -36,63 +36,109 @@ DESCRIPTION
|
|||||||
date-format %d/%m/%Y
|
date-format %d/%m/%Y
|
||||||
skip 1
|
skip 1
|
||||||
|
|
||||||
A more complete example:
|
More examples in the EXAMPLES section below.
|
||||||
|
|
||||||
# hledger CSV rules for amazon.com order history
|
|
||||||
|
|
||||||
# sample:
|
|
||||||
# "Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID"
|
|
||||||
# "Jul 29, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$0.00","17LA58JSK6PRD4HDGLNJQPI1PB9N8DKPVHL"
|
|
||||||
|
|
||||||
# skip one header line
|
|
||||||
skip 1
|
|
||||||
|
|
||||||
# name the csv fields (and assign the transaction's date, amount and code)
|
|
||||||
fields date, _, toorfrom, name, amzstatus, amount, fees, code
|
|
||||||
|
|
||||||
# how to parse the date
|
|
||||||
date-format %b %-d, %Y
|
|
||||||
|
|
||||||
# combine two fields to make the description
|
|
||||||
description %toorfrom %name
|
|
||||||
|
|
||||||
# save these fields as tags
|
|
||||||
comment status:%amzstatus, fees:%fees
|
|
||||||
|
|
||||||
# set the base account for all transactions
|
|
||||||
account1 assets:amazon
|
|
||||||
|
|
||||||
# flip the sign on the amount
|
|
||||||
amount -%amount
|
|
||||||
|
|
||||||
For more examples, see Convert CSV files.
|
|
||||||
|
|
||||||
CSV RULES
|
CSV RULES
|
||||||
The following seven kinds of rule can appear in the rules file, in any
|
The following kinds of rule can appear in the rules file, in any order
|
||||||
order. Blank lines and lines beginning with # or ; are ignored.
|
(except for end which can appear only inside a conditional block).
|
||||||
|
Blank lines and lines beginning with # or ; are ignored.
|
||||||
|
|
||||||
skip
|
skip
|
||||||
skipN
|
skip N
|
||||||
|
|
||||||
Skip this many non-empty lines preceding the CSV data. (Empty/blank
|
The word "skip" followed by a number (or no number, meaning 1) tells
|
||||||
lines are skipped automatically.) You'll need this whenever your CSV
|
hledger to ignore this many non-empty lines preceding the CSV data.
|
||||||
data contains header lines. Eg:
|
(Empty/blank lines are skipped automatically.) You'll need this when-
|
||||||
|
ever your CSV data contains header lines.
|
||||||
|
|
||||||
# ignore the first CSV line
|
It also has a second purpose: it can be used to ignore certain CSV
|
||||||
skip 1
|
records, see conditional blocks below.
|
||||||
|
|
||||||
|
fields
|
||||||
|
fields FIELDNAME1, FIELDNAME2, ...
|
||||||
|
|
||||||
|
A fields list ("fields" followed by one or more comma-separated field
|
||||||
|
names) is the quick way to assign CSV field values to hledger fields.
|
||||||
|
It (a) names the CSV fields, in order (names may not contain white-
|
||||||
|
space; fields you don't care about can be left unnamed), and (b) as-
|
||||||
|
signs them to hledger fields if you use standard hledger field names.
|
||||||
|
Here's an example:
|
||||||
|
|
||||||
|
# use the 1st, 2nd and 4th CSV fields as the transaction's date, description and amount,
|
||||||
|
# ignore the 3rd, 5th and 6th fields,
|
||||||
|
# and name the 7th and 8th fields for later reference:
|
||||||
|
# 1 2 3 4 5 6 7 8
|
||||||
|
|
||||||
|
fields date, description, , amount1, , , somefield, anotherfield
|
||||||
|
|
||||||
|
Here are the standard hledger field names:
|
||||||
|
|
||||||
|
Transaction fields
|
||||||
|
date, date2, status, code, description, comment can be used to form the
|
||||||
|
transaction's first line. Only date is required. (See also date-for-
|
||||||
|
mat below.)
|
||||||
|
|
||||||
|
Posting fields
|
||||||
|
accountN, where N is 1 to 9, sets the Nth posting's account name. Most
|
||||||
|
often there are two postings, so you'll want to set account1 and ac-
|
||||||
|
count2.
|
||||||
|
|
||||||
|
A number of field/pseudo-field names are available for setting posting
|
||||||
|
amounts:
|
||||||
|
|
||||||
|
o amountN sets posting N's amount
|
||||||
|
|
||||||
|
o amountN-in and amountN-out can be used instead, if the CSV has sepa-
|
||||||
|
rate fields for debits and credits
|
||||||
|
|
||||||
|
o currencyN sets a currency symbol to be left-prefixed to the amount,
|
||||||
|
useful if the CSV provides that as a separate field
|
||||||
|
|
||||||
|
o balanceN sets a (separate) balance assertion amount (or when no post-
|
||||||
|
ing amount is set, a balance assignment)
|
||||||
|
|
||||||
|
If you write these with no number (amount, amount-in, amount-out, cur-
|
||||||
|
rency, balance), it means posting 1. Also, if you set an amount for
|
||||||
|
posting 1 only, a second posting that balances the transaction will be
|
||||||
|
generated automatically. This helps support CSV rules created before
|
||||||
|
hledger 1.16.
|
||||||
|
|
||||||
|
Finally, commentN sets a comment on the Nth posting. Comments can of
|
||||||
|
course contain tags.
|
||||||
|
|
||||||
|
(field assignment)
|
||||||
|
HLEDGERFIELDNAME FIELDVALUE
|
||||||
|
|
||||||
|
Instead of or in addition to a fields list, you can assign a value to a
|
||||||
|
hledger field by writing its name (any of the standard names above)
|
||||||
|
followed by a text value. The value may contain interpolated CSV
|
||||||
|
fields, referenced by their 1-based position in the CSV record (%N), or
|
||||||
|
by the name they were given in the fields list (%CSVFIELDNAME). Eg:
|
||||||
|
|
||||||
|
# set the amount to the 4th CSV field, with " USD" appended
|
||||||
|
amount %4 USD
|
||||||
|
|
||||||
|
# combine three fields to make a comment, containing note: and date: tags
|
||||||
|
comment note: %somefield - %anotherfield, date: %1
|
||||||
|
|
||||||
|
Interpolation strips any outer whitespace, so a CSV value like " 1 "
|
||||||
|
becomes 1 when interpolated (#1051). Note you can only interpolate CSV
|
||||||
|
fields, not the hledger fields being assigned to; for more on this, see
|
||||||
|
TIPS.
|
||||||
|
|
||||||
date-format
|
date-format
|
||||||
date-formatDATEFMT
|
date-format DATEFMT
|
||||||
|
|
||||||
When your CSV date fields are not formatted like YYYY/MM/DD (or YYYY-
|
This is a helper for the date (and date2) fields. If your CSV dates
|
||||||
MM-DD or YYYY.MM.DD), you'll need to specify the format. DATEFMT is a
|
are not formatted like YYYY-MM-DD, YYYY/MM/DD or YYYY.MM.DD, you'll
|
||||||
strptime-like date parsing pattern, which must parse the date field
|
need to specify the format by writing "date-format" followed by a strp-
|
||||||
values completely. Examples:
|
time-like date parsing pattern, which must parse the date field values
|
||||||
|
completely. Examples:
|
||||||
|
|
||||||
# for dates like "11/06/2013":
|
# for dates like "11/06/2013":
|
||||||
date-format %m/%d/%Y
|
date-format %m/%d/%Y
|
||||||
|
|
||||||
# for dates like "6/11/2013" (note the - to make leading zeros optional):
|
# for dates like "6/11/2013". The - allows leading zeros to be optional.
|
||||||
date-format %-d/%-m/%Y
|
date-format %-d/%-m/%Y
|
||||||
|
|
||||||
# for dates like "2013-Nov-06":
|
# for dates like "2013-Nov-06":
|
||||||
@ -101,59 +147,41 @@ CSV RULES
|
|||||||
# for dates like "11/6/2013 11:32 PM":
|
# for dates like "11/6/2013 11:32 PM":
|
||||||
date-format %-m/%-d/%Y %l:%M %p
|
date-format %-m/%-d/%Y %l:%M %p
|
||||||
|
|
||||||
field list
|
if
|
||||||
fieldsFIELDNAME1, FIELDNAME2...
|
if PATTERN
|
||||||
|
RULE
|
||||||
|
|
||||||
This (a) names the CSV fields, in order (names may not contain white-
|
if
|
||||||
space; uninteresting names may be left blank), and (b) assigns them to
|
PATTERN
|
||||||
journal entry fields if you use any of these standard field names:
|
PATTERN
|
||||||
date, date2, status, code, description, comment, account1, account2,
|
PATTERN
|
||||||
amount, amount-in, amount-out, currency, balance, balance1, balance2.
|
RULE
|
||||||
Eg:
|
RULE
|
||||||
|
|
||||||
# use the 1st, 2nd and 4th CSV fields as the entry's date, description and amount,
|
Conditional blocks apply one or more rules to CSV records which are
|
||||||
# and give the 7th and 8th fields meaningful names for later reference:
|
matched by any of the PATTERNs. This allows transactions to be cus-
|
||||||
#
|
tomised or categorised based on patterns in the data.
|
||||||
# CSV field:
|
|
||||||
# 1 2 3 4 5 6 7 8
|
|
||||||
# entry field:
|
|
||||||
fields date, description, , amount, , , somefield, anotherfield
|
|
||||||
|
|
||||||
field assignment
|
A single pattern can be written on the same line as the "if"; or multi-
|
||||||
ENTRYFIELDNAME FIELDVALUE
|
ple patterns can be written on the following lines, non-indented.
|
||||||
|
|
||||||
This sets a journal entry field (one of the standard names above) to
|
Patterns are case-insensitive regular expressions which try to match
|
||||||
the given text value, which can include CSV field values interpolated
|
any part of the whole CSV record. It's not yet possible to match
|
||||||
by name (%CSVFIELDNAME) or 1-based position (%N). Eg:
|
within a specific field. Note the CSV record they see is close but not
|
||||||
|
identical to the one in the CSV file; eg double quotes are removed, and
|
||||||
|
the separator character becomes comma.
|
||||||
|
|
||||||
# set the amount to the 4th CSV field with "USD " prepended
|
After the patterns, there should be one or more rules to apply, all in-
|
||||||
amount USD %4
|
dented by at least one space. Three kinds of rule are allowed in con-
|
||||||
|
ditional blocks:
|
||||||
|
|
||||||
# combine three fields to make a comment (containing two tags)
|
o field assignments (to set a field's value)
|
||||||
comment note: %somefield - %anotherfield, date: %1
|
|
||||||
|
|
||||||
Field assignments can be used instead of or in addition to a field
|
o skip (to skip the matched CSV record)
|
||||||
list.
|
|
||||||
|
|
||||||
Note, interpolation strips any outer whitespace, so a CSV value like "
|
o end (to skip all remaining CSV records).
|
||||||
1 " becomes 1 when interpolated (#1051).
|
|
||||||
|
|
||||||
conditional block
|
Examples:
|
||||||
if PATTERN
|
|
||||||
FIELDASSIGNMENTS...
|
|
||||||
|
|
||||||
if
|
|
||||||
PATTERN
|
|
||||||
PATTERN...
|
|
||||||
FIELDASSIGNMENTS...
|
|
||||||
|
|
||||||
This applies one or more field assignments, only to those CSV records
|
|
||||||
matched by one of the PATTERNs. The patterns are case-insensitive reg-
|
|
||||||
ular expressions which match anywhere within the whole CSV record (it's
|
|
||||||
not yet possible to match within a specific field). When there are
|
|
||||||
multiple patterns they can be written on separate lines, unindented.
|
|
||||||
The field assignments are on separate lines indented by at least one
|
|
||||||
space. Examples:
|
|
||||||
|
|
||||||
# if the CSV record contains "groceries", set account2 to "expenses:groceries"
|
# if the CSV record contains "groceries", set account2 to "expenses:groceries"
|
||||||
if groceries
|
if groceries
|
||||||
@ -167,90 +195,250 @@ CSV RULES
|
|||||||
account2 expenses:business:banking
|
account2 expenses:business:banking
|
||||||
comment XXX deductible ? check it
|
comment XXX deductible ? check it
|
||||||
|
|
||||||
|
end
|
||||||
|
As mentioned above, this rule can be used inside conditional blocks
|
||||||
|
(only) to cause hledger to stop reading CSV records and proceed with
|
||||||
|
command execution. Eg:
|
||||||
|
|
||||||
|
# ignore everything following the first empty record
|
||||||
|
if ,,,,
|
||||||
|
end
|
||||||
|
|
||||||
include
|
include
|
||||||
includeRULESFILE
|
include RULESFILE
|
||||||
|
|
||||||
Include another rules file at this point. RULESFILE is either an abso-
|
Include another CSV rules file at this point, as if it were written in-
|
||||||
lute file path or a path relative to the current file's directory. Eg:
|
line. RULESFILE is an absolute file path or a path relative to the
|
||||||
|
current file's directory.
|
||||||
|
|
||||||
# rules reused with several CSV files
|
This can be useful eg for reusing common rules in several rules files:
|
||||||
include common.rules
|
|
||||||
|
# someaccount.csv.rules
|
||||||
|
|
||||||
|
## someaccount-specific rules
|
||||||
|
fields date,description,amount
|
||||||
|
account1 some:account
|
||||||
|
account2 some:misc
|
||||||
|
|
||||||
|
## common rules
|
||||||
|
include categorisation.rules
|
||||||
|
|
||||||
newest-first
|
newest-first
|
||||||
newest-first
|
hledger always sorts the generated transactions by date. Transactions
|
||||||
|
on the same date should appear in the same order as their CSV records,
|
||||||
|
as hledger can usually auto-detect whether the CSV's normal order is
|
||||||
|
oldest first or newest first. But if all of the following are true:
|
||||||
|
|
||||||
Consider adding this rule if all of the following are true: you might
|
o the CSV might sometimes contain just one day of data (all records
|
||||||
be processing just one day of data, your CSV records are in reverse
|
having the same date)
|
||||||
chronological order (newest first), and you care about preserving the
|
|
||||||
order of same-day transactions. It usually isn't needed, because
|
|
||||||
hledger autodetects the CSV order, but when all CSV records have the
|
|
||||||
same date it will assume they are oldest first.
|
|
||||||
|
|
||||||
CSV TIPS
|
o the CSV records are normally in reverse chronological order (newest
|
||||||
CSV ordering
|
first)
|
||||||
The generated journal entries will be sorted by date. The order of
|
|
||||||
same-day entries will be preserved (except in the special case where
|
|
||||||
you might need newest-first, see above).
|
|
||||||
|
|
||||||
CSV accounts
|
o and you care about preserving the order of same-day transactions
|
||||||
Each journal entry will have two postings, to account1 and account2 re-
|
|
||||||
spectively. It's not yet possible to generate entries with more than
|
|
||||||
two postings. It's conventional and recommended to use account1 for
|
|
||||||
the account whose CSV we are reading.
|
|
||||||
|
|
||||||
CSV amounts
|
you should add the newest-first rule as a hint. Eg:
|
||||||
A transaction amount must be set, in one of these ways:
|
|
||||||
|
|
||||||
o with an amount field assignment, which sets the first posting's
|
# tell hledger explicitly that the CSV is normally newest-first
|
||||||
amount
|
newest-first
|
||||||
|
|
||||||
o (When the CSV has debit and credit amounts in separate fields:)
|
EXAMPLES
|
||||||
with field assignments for the amount-in and amount-out pseudo fields
|
A more complete example, generating three-posting transactions:
|
||||||
(both of them). Whichever one has a value will be used, with appropri-
|
|
||||||
ate sign. If both contain a value, it might not work so well.
|
|
||||||
|
|
||||||
o or implicitly by means of a balance assignment (see below).
|
# hledger CSV rules for amazon.com order history
|
||||||
|
|
||||||
|
# sample:
|
||||||
|
# "Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID"
|
||||||
|
# "Jul 29, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$0.00","17LA58JSK6PRD4HDGLNJQPI1PB9N8DKPVHL"
|
||||||
|
|
||||||
|
# skip one header line
|
||||||
|
skip 1
|
||||||
|
|
||||||
|
# name the csv fields (and assign the transaction's date, amount and code)
|
||||||
|
fields date, _, toorfrom, name, amzstatus, amount1, fees, code
|
||||||
|
|
||||||
|
# how to parse the date
|
||||||
|
date-format %b %-d, %Y
|
||||||
|
|
||||||
|
# combine two fields to make the description
|
||||||
|
description %toorfrom %name
|
||||||
|
|
||||||
|
# save these fields as tags
|
||||||
|
comment status:%amzstatus
|
||||||
|
|
||||||
|
# set the base account for all transactions
|
||||||
|
account1 assets:amazon
|
||||||
|
|
||||||
|
# flip the sign on the amount
|
||||||
|
amount -%amount
|
||||||
|
|
||||||
|
# Put fees in a separate posting
|
||||||
|
amount3 %fees
|
||||||
|
comment3 fees
|
||||||
|
|
||||||
|
For more examples, see Convert CSV files.
|
||||||
|
|
||||||
|
TIPS
|
||||||
|
Reading multiple CSV files
|
||||||
|
You can read multiple CSV files at once using multiple -f arguments on
|
||||||
|
the command line. hledger will look for a correspondingly-named rules
|
||||||
|
file for each CSV file. If you use the --rules-file option, that rules
|
||||||
|
file will be used for all the CSV files.
|
||||||
|
|
||||||
|
Deduplicating, importing
|
||||||
|
When you download a CSV file repeatedly, eg to get your latest bank
|
||||||
|
transactions, the new file may contain some of the same records as the
|
||||||
|
old one. The print --new command is one simple way to detect just the
|
||||||
|
new transactions. Or better still, the import command appends those
|
||||||
|
new transactions to your main journal. This is the easiest way to im-
|
||||||
|
port CSV data. Eg, after downloading your latest CSV files:
|
||||||
|
|
||||||
|
$ hledger import *.csv [--dry]
|
||||||
|
|
||||||
|
Other import methods
|
||||||
|
A number of other tools and workflows, hledger-specific and otherwise,
|
||||||
|
exist for converting, deduplicating, classifying and managing CSV data.
|
||||||
|
See:
|
||||||
|
|
||||||
|
o https://hledger.org -> sidebar -> real world setups
|
||||||
|
|
||||||
|
o https://plaintextaccounting.org -> data import/conversion
|
||||||
|
|
||||||
|
Valid CSV
|
||||||
|
hledger accepts CSV conforming to RFC 4180. Some things to note when
|
||||||
|
values are enclosed in quotes:
|
||||||
|
|
||||||
|
o you must use double quotes (not single quotes)
|
||||||
|
|
||||||
|
o spaces outside the quotes are not allowed
|
||||||
|
|
||||||
|
Other separator characters
|
||||||
|
With the --separator 'CHAR' option, hledger will expect the separator
|
||||||
|
to be CHAR instead of a comma. Ie it will read other "Character Sepa-
|
||||||
|
rated Values" formats, such as TSV (Tab Separated Values). Note: on
|
||||||
|
the command line, use a real tab character in quotes, not Eg:
|
||||||
|
|
||||||
|
$ hledger -f foo.tsv --separator ' ' print
|
||||||
|
|
||||||
|
(Experimental.)
|
||||||
|
|
||||||
|
Setting amounts
|
||||||
|
A posting amount can be set in one of these ways:
|
||||||
|
|
||||||
|
o by assigning (with a fields list or field assigment) to amountN
|
||||||
|
(posting N's amount) or amount (posting 1's amount)
|
||||||
|
|
||||||
|
o by assigning to amountN-in and amountN-out (or amount-in and amount-
|
||||||
|
out). For each CSV record, whichever of these has a non-zero value
|
||||||
|
will be used, with appropriate sign. If both contain a non-zero
|
||||||
|
value, this may not work.
|
||||||
|
|
||||||
|
o by assigning to balanceN (or balance) instead of the above, setting
|
||||||
|
the amount indirectly via a balance assignment.
|
||||||
|
|
||||||
There is some special handling for sign in amounts:
|
There is some special handling for sign in amounts:
|
||||||
|
|
||||||
o If an amount value is parenthesised, it will be de-parenthesised and
|
o If an amount value is parenthesised, it will be de-parenthesised and
|
||||||
sign-flipped.
|
sign-flipped.
|
||||||
|
|
||||||
o If an amount value begins with a double minus sign, those will cancel
|
o If an amount value begins with a double minus sign, those cancel out
|
||||||
out and be removed.
|
and are removed.
|
||||||
|
|
||||||
If the currency/commodity symbol is provided as a separate CSV field,
|
If the currency/commodity symbol is provided as a separate CSV field,
|
||||||
assign it to the currency pseudo field; the symbol will be prepended to
|
you can assign it to currency (affects all posting amounts) or curren-
|
||||||
the amount (TODO: when there is an amount). Or, you can use an amount
|
cyN (affects just posting N's amount). The symbol will be prepended to
|
||||||
field assignment for more control, eg:
|
the amount. Or for more control, you can set both currency symbol and
|
||||||
|
amount with a field assignment, eg:
|
||||||
|
|
||||||
fields date,description,currency,amount
|
fields date,description,currency,amount
|
||||||
|
# add currency symbol on the right:
|
||||||
amount %amount %currency
|
amount %amount %currency
|
||||||
|
|
||||||
CSV balance assertions/assignments
|
Referencing other fields
|
||||||
If the CSV includes a running balance, you can assign that to one of
|
In field assignments, you can interpolate only CSV fields, not hledger
|
||||||
the pseudo fields balance (or balance1) or balance2. This will gener-
|
fields. In the example below, there's both a CSV field and a hledger
|
||||||
ate a balance assertion (or if the amount is left empty, a balance as-
|
field named amount1, but %amount1 always means the CSV field, not the
|
||||||
signment), on the first or second posting, whenever the running balance
|
hledger field:
|
||||||
field is non-empty. (TODO: #1000)
|
|
||||||
|
|
||||||
Reading multiple CSV files
|
# Name the third CSV field "amount1"
|
||||||
You can read multiple CSV files at once using multiple -f arguments on
|
fields date,description,amount1
|
||||||
the command line, and hledger will look for a correspondingly-named
|
|
||||||
rules file for each. Note if you use the --rules-file option, this one
|
|
||||||
rules file will be used for all the CSV files being read.
|
|
||||||
|
|
||||||
Valid CSV
|
# Set hledger's amount1 to the CSV amount1 field followed by USD
|
||||||
hledger follows RFC 4180, with the addition of a customisable separator
|
amount1 %amount1 USD
|
||||||
character.
|
|
||||||
|
|
||||||
Some things to note:
|
# Set comment to the CSV amount1 (not the amount1 assigned above)
|
||||||
|
comment %amount1
|
||||||
|
|
||||||
When quoting fields,
|
Here, since there's no CSV amount1 field, %amount1 will produce a lit-
|
||||||
|
eral "amount1":
|
||||||
|
|
||||||
o you must use double quotes, not single quotes
|
fields date,description,csvamount
|
||||||
|
amount1 %csvamount USD
|
||||||
|
# Can't interpolate amount1 here
|
||||||
|
comment %amount1
|
||||||
|
|
||||||
o spaces outside the quotes are not allowed.
|
When there are multiple field assignments to the same hledger field,
|
||||||
|
only the last one takes effect. Here, comment's value will be be B, or
|
||||||
|
C if "something" is matched, but never A:
|
||||||
|
|
||||||
|
comment A
|
||||||
|
comment B
|
||||||
|
if something
|
||||||
|
comment C
|
||||||
|
|
||||||
|
How CSV rules are evaluated
|
||||||
|
Here's how to think of CSV rules being evaluated (if you really need
|
||||||
|
to). First,
|
||||||
|
|
||||||
|
o include - all includes are inlined, from top to bottom, depth first.
|
||||||
|
(At each include point the file is inlined and scanned for further
|
||||||
|
includes, before proceeding.)
|
||||||
|
|
||||||
|
Then "global" rules are evaluated, top to bottom. If a rule is re-
|
||||||
|
peated, the last one wins:
|
||||||
|
|
||||||
|
o skip (at top level)
|
||||||
|
|
||||||
|
o date-format
|
||||||
|
|
||||||
|
o newest-first
|
||||||
|
|
||||||
|
o fields - names the CSV fields, optionally sets up initial assignments
|
||||||
|
to hledger fields
|
||||||
|
|
||||||
|
Then for each CSV record in turn:
|
||||||
|
|
||||||
|
o test all if blocks. If any of them contain a end rule, skip all re-
|
||||||
|
maining CSV records. Otherwise if any of them contain a skip rule,
|
||||||
|
skip that many CSV records. If there are multiple matched skip
|
||||||
|
rules, the first one wins.
|
||||||
|
|
||||||
|
o collect all field assignments at top level and in matched if blocks.
|
||||||
|
When there are multiple assignments for a field, keep only the last
|
||||||
|
one.
|
||||||
|
|
||||||
|
o compute a value for each hledger field - either the one that was as-
|
||||||
|
signed to it (and interpolate the %CSVFIELDNAME references), or a de-
|
||||||
|
fault
|
||||||
|
|
||||||
|
o generate a synthetic hledger transaction from these values, which be-
|
||||||
|
comes part of the input to the hledger command that has been selected
|
||||||
|
|
||||||
|
Valid transactions
|
||||||
|
hledger currently does not post-process and validate transactions gen-
|
||||||
|
erated from CSV as thoroughly as transactions read from a journal file.
|
||||||
|
This means that if your rules are wrong, you can generate invalid
|
||||||
|
transactions. Or, amounts may not be displayed with a canonical dis-
|
||||||
|
play style.
|
||||||
|
|
||||||
|
So when setting up or adjusting CSV rules, you should check your re-
|
||||||
|
sults visually with the print command. You can pipe print's output
|
||||||
|
through hledger once more to validate and canonicalise fully. Eg:
|
||||||
|
|
||||||
|
$ hledger -f some.csv print | hledger -f- print -I
|
||||||
|
|
||||||
|
(The -I/--ignore-assertions flag disables balance assertion checks,
|
||||||
|
usually needed when re-parsing print output.)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user