Ledger-cliでレシートのタイムスタンプを記録・処理してみる

Ledger-cliではトランザクションに時刻を打つことは標準では用意されていません。

家計簿でもスモールビジネスでもふつうはレシートの時刻を求められることはありませんので、なんの差し障りもありません。

けれども、つい最近 ごく一部のレシートについては時刻を記録するようになりました。

旅行先で色々な場所を移動した後にその記録を書いているときに、どのような順番で移動したかは、レシート時刻を参照するとよいことに気づきました1

ここではLedger-cliでレシート時刻を記録し処理する一つの方法を紹介します。

トランザクションの書き方

Ledger-cliで用意されているタグを使います。

タグの名前は Recpt-TS (Receipt Time Stamp)、その として時刻を %H:%M フォーマットで記録します。たとえば:

2023/10/04 角上魚類
    ; Recpt-TS: 13:37
    Expenses:Grocery:Food:KAT             3,565 JPY
    Liabilities:VisaCard

これでLedger-cliはこのトランザクションに Recpt-TS: 13:37 というタグとその値をつけてくれます。

クエリのサンプル

もっとも簡単な例

指定した日のトランザクションの中でレシート時刻のあるレコードを表示します2

$ ledger print %recpt -p 09/03
2023/09/03 ENEOS SS
    ; Recpt-TS: 12:04
    ; 15.17L @183 JPY
    Expenses:Cars:Gasoline                 2,776 JPY
    Liabilities:EneosCard

2023/09/03 ベイシア
    ; Recpt-TS: 13:57
    Expenses:Grocery:Food:KAT
    Liabilities:VisaCard                 -4,687 JPY

やや実用的な例

2023/09月中のトランザクションからレシート時刻のあるレコードを抽出して、「日付、時刻、支払先」を表示します。クエリは次のとおりです3

$ ledger reg %recpt and \( ^liab or ^assets \)\
     --format '%(date) %(tag(/recpt/) %(payee))\n'\
	 -b 09/01 -e 10/01

表示される出力はこんな感じ:

2023/09/03 11:11 角上魚類
2023/09/03 12:04 ENEOS SS
2023/09/03 13:57 ベイシア
2023/09/21 11:48 ENEOS SS
2023/09/21 13:05 ジャパンミート
2023/09/21 12:21 バーガーキング
2023/09/21 13:12 ジョイホンパーク吉岡
2023/09/21 13:23 ABC-mart
2023/09/21 13:54 角上魚類
2023/09/21 14:33 ツルヤ
2023/09/28 10:41 ベイシア
2023/09/28 10:41 クロネコ
2023/09/28 12:20 ENEOS SS
2023/09/28 12:53 マクドナルド
2023/09/28 13:33 角上魚類
  • よく見ると、09/21の「ジャパンミート」と「バーガーキング」の時刻順が逆になっています。それを直すには sort -k1,1 -k3,3n すればよいのですが、一つ問題があります。

  • 支払先名(payee)の ENEOS SS 内に半角スペースが含まれています。このままでは sort 時にトラブルを起こしますので、あらかじめ半角スペースをアンダーバーにでも書き換えておきます4

    sed 's/ENEOS SS/ENEOS_SS/g'
    

まとめると

$ ledger reg %recpt and \( ^liab or ^assets \)\
     --format '%(date) %(tag(/recpt/)) %(payee)\n'\
	 -b 09/01 -e 10/01\
	 | sed 's/ENEOS SS/ENEOS_SS/g'\
	 | sort -k1,1 -k3,3n

結果は次のようになります。

2023/09/03 11:11 角上魚類
2023/09/03 12:04 ENEOS_SS
2023/09/03 13:57 ベイシア
2023/09/21 11:48 ENEOS_SS
2023/09/21 12:21 バーガーキング
2023/09/21 13:05 ジャパンミート
2023/09/21 13:12 ジョイホンパーク吉岡
2023/09/21 13:23 ABC-mart
2023/09/21 13:54 角上魚類
2023/09/21 14:33 ツルヤ
2023/09/28 10:41 クロネコ
2023/09/28 10:41 ベイシア
2023/09/28 12:20 ENEOS_SS
2023/09/28 12:53 マクドナルド
2023/09/28 13:33 角上魚類

応用

上の出力の行末に 金額 を追加してCSVファイルに保存するには:

$ ledger reg %recpt and \( ^liab or ^assets \)\
     --format '%(date),%(tag(/recpt/)),%(payee),"%(amount)"\n'\
     -b 09/01 -e 10/01\
     | sed 's/ENEOS SS/ENEOS_SS/g'\
     | sort -k1,1 -k3,3n \
     > tmp.csv

tmp.csvの中身はこんな感じ:

2023/09/03,11:11,角上魚類,"-1,740 JPY"
2023/09/03,12:04,ENEOS_SS,"-2,776 JPY"
2023/09/03,13:57,ベイシア,"-4,687 JPY"
2023/09/21,11:48,ENEOS_SS,"-3,640 JPY"
2023/09/21,12:21,バーガーキング,"-1,200 JPY"
2023/09/21,13:05,ジャパンミート,"-3,459 JPY"
2023/09/21,13:12,ジョイホンパーク吉岡,"-437 JPY"
2023/09/21,13:23,ABC-mart,"-5,390 JPY"
2023/09/21,13:54,角上魚類,"-4,988 JPY"
2023/09/21,14:33,ツルヤ,"-5,011 JPY"
2023/09/28,10:41,クロネコ,"-852 JPY"
2023/09/28,10:41,ベイシア,"-828 JPY"
2023/09/28,12:20,ENEOS_SS,"-7,565 JPY"
2023/09/28,12:53,マクドナルド,"-550 JPY"
2023/09/28,13:33,角上魚類,"-5,193 JPY"
  • 金額がマイナス表示されてますが、これを直すには上のクエリの "%(amount)""%(-amount)" にします。
  • ENEOS_SS が気になるのなら、ここでsedを使って元の ENEOS SS に戻します5

他の使い方?

個人レベルでは、旅行や出張などの移動経路の確認のために補助記録として使う他に使い方を思いつきません。何かよいアイデアがあれば教えて欲しいです。

最近話題のインボイスでもレシート時刻が求められることは無いようです。わが国では日付抜き、宛名抜きの手書き領収書がお偉いさんの間では重宝されていますので、時刻なんぞはとんでもないのでしょうか。


  1. 人が移動すると なんだかんだとお金を使うんですね 😅 ↩︎

  2. 私のLedgerファイルではENEOSのトランザクションにはガソリン給油量と単価がノート(コメント)として入っています。これを Recpt-TS と同じ行に書くと面倒なことが起こります。 ↩︎

  3. \( ^liab or ^assets \) にしているのは、これを簡単に ^Expenses にすると、一つのトランザクションで複数の行の支出があると、それらが全部表示されてしまいます。それを避けるためですがもっとスマートな方法が他にあるのではないかと思います。 ↩︎

  4. Ledgerでは支払先にスペースを入れてもOKですが、後々のことを考えると、できるなら避けた方が良いのかもしれません。 ↩︎

  5. ENEOS SS に戻す際には sed 's/ENEOS_SS/"ENEOS SS"/g' tmp1.csv してダブルクォートで囲んだ方がよいかも。 ↩︎