-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathn2hb
77 lines (63 loc) · 2.11 KB
/
n2hb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/bin/bash
#
# n2hb: Nordea to HomeBank
#
DEFAULT_DIR="$(xdg-user-dir DOWNLOAD || pwd)"
error()
{
echo "$*" 1>&2
exit 1
}
[[ $1 = --help ]] && exec cat<<EOF
Usage: n2hb [FILE] ...
Convert CSV from Nordea.se to the format used by HomeBank.
Defaults to parsing ~/Downloads/*.csv.
EOF
if [[ $@ ]]; then
files=("$@")
else
files=()
while read; do
files+=("$REPLY")
done < <(find "$DEFAULT_DIR/" -type f -name "*.csv" -not -name "homebank_conv*")
[[ $files ]] || error "no csv files found in $DEFAULT_DIR"
fi
for file in "${files[@]}"; do
head -n1 "$file" | grep -Eq "^(.*,){3}|^(.*;){7}" || error "$file: bad file format"
done
savefile="$(date '+homebank_conv_%Y-%m-%d_%H-%M-%S.csv')"
for file in "${files[@]}"; do
# Show dates contained in each file
echo "$file: $(grep -Eo '^[0-9]{4}-[0-9]{2}' "$file" | sort -u | tr '\n' ' ')" >&2
# HomeBank CSV format:
# YY-MM-DD; [Type, 0 = none]; [Payment info]; [Payee]; Description; Amount (-NNNN,NN); [Category]; [Tags]
number='([-0-9,]+)'
if head -n1 "$file" | grep -Eq "^(.*,){4}"; then
# Nordea old format:
# YYYY-MM-DD, Description, Category, Amount ("-N.NNN,NN"), Balance
# BUG: breaks if you transfer 1.000.000 but in that case you may pay me to find a better solution
any='("[^"]*"|[^,]*)'
fmt="s/^20$number,$any,$any,\"($number\.)?$number\",$any\$/\1;0;;;\2;\5\6;;/p"
elif head -n1 "$file" | grep -Eq "^(.*;){7}"; then
# Nordea new format:
# YYYY-MM-DD; Amount (-NNNN,NN); From; [Payee]; [Name]; Description; Balance; Currency
any='("[^"]*"|[^;]*)'
fmt="s/^20$number;$number;$any;$any;$any;$any;$any;$any\$/\1;0;;;\6;\2;;;/p"
else
echo "$file: unknown format" >&2
fi
sed -En "
# Delete first line
1 d
# Delete empty lines (last one for the old format)
/^\r?$/d
# Print good lines to stdout
$fmt
# If line was good, go to next
t
# Write to stderr (GNU only)
s/^/invalid line: /
w /dev/stderr
" < "$file"
done > "$savefile"
echo "created $savefile"