Skip to content

Instantly share code, notes, and snippets.

@eloyesp
Created August 18, 2017 14:43
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eloyesp/0781347c32d0aa28f0e35383f1f20575 to your computer and use it in GitHub Desktop.
Save eloyesp/0781347c32d0aa28f0e35383f1f20575 to your computer and use it in GitHub Desktop.
Migrate GNUcash to ledger-cli
# gnucash2ledger.rb
#
# Usage:
# ruby gnucash2ledger.rb < origen.gnucash > destino.ledger
#
# Make sure that the gnucash file is uncompressed
require 'nokogiri'
require 'date'
require 'bigdecimal'
gnucash_file = Nokogiri::XML(ARGF)
gnucash_file.remove_namespaces!
transactions = gnucash_file.xpath('//transaction')
class Account
attr_reader :name, :currency
def initialize name, currency
@name = name
@currency = currency
end
end
accounts = Hash.new do |memo, guid|
account = gnucash_file.xpath("//account/id[text() = '#{ guid }']/..")
parent = account.xpath('parent')
if parent.empty?
name = nil
else
parent_account = accounts[parent.inner_text]
name = [parent_account.name, account.xpath('name').inner_text].compact.join(':')
end
currency = account.xpath('commodity/id').inner_text
account = Account.new name, currency
memo[guid] = account
end
transactions.each do |transaction|
date = Date.parse transaction.xpath('date-posted/date').first
description = transaction.xpath('description').first.content
currency = transaction.xpath('currency/id').first.content
splits = transaction.xpath 'splits/split'
puts "#{ date } #{ description }"
splits.each do |split|
account_id = split.xpath('account').inner_text
account = accounts[account_id]
ammount = split.xpath('quantity').inner_text.to_r.to_f
puts " %-35s % 4.2f %s" % [account.name, ammount, account.currency]
end
puts
end
@SitanHuang
Copy link

Ledger-cli stopped supporting gnucash format, and came across this script. Thank you so so much!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment