costs

Tool to help you see the impact of recurring costs
git clone git://jacobedwards.org/costs
Log | Files | Refs | README

costs.awk (1517B)


      1 #!/usr/bin/awk -f
      2 # Copyright 2023 Jacob R. Edwards <jacob@jacobedwards.org>
      3 
      4 function error(msg) {
      5 	print("error: " msg) > "/dev/stderr";
      6 }
      7 
      8 function die(msg) {
      9 	status = msg;
     10 	error(status);
     11 	exit 1
     12 }
     13 
     14 BEGIN {
     15 	FS = "	";
     16 	OFS = FS;
     17 	OFMT = "%.2f";
     18 
     19 	period = 1;
     20 	amount = 2;
     21 	name = 3;
     22 	desc = 4;
     23 
     24 	t["daily"] = 1;
     25 	t["weekly"] = 7;
     26 	t["bi-weekly"] = 14;
     27 	t["monthly"] = 365 / 12 # 'spose 30 or 30.4 could produce easier numbers
     28 	t["quarterly"] = t["monthly"] * 3;
     29 	t["yearly"] = 365;
     30 
     31 	output = "daily";
     32 
     33 	if (ARGC > 1) {
     34 		if (ARGV[1] != "-") {
     35 			output = ARGV[1];
     36 			if (!(output in t))
     37 				die(output " not a valid period");
     38 		}
     39 		delete ARGV[1];
     40 		if (ARGC > 1) {
     41 			prefix = ARGV[2];
     42 			delete ARGV[2];
     43 			if (ARGC > 3) {
     44 				die("usage: costs [period [prefix]]")
     45 			}
     46 		}
     47 	}
     48 }
     49 
     50 /^[^# ]/ && ! /^$/ && (prefix == "" || index($name, prefix) == 1) {
     51 	m = 1
     52 	n = split($period, ts, "/")
     53 	if (n > 2 || !(ts[1] in t) || (n > 2 && ts[2] == 0))
     54 		die($period ": Invalid period")
     55 
     56 	if (n > 1)
     57 		m = ts[2]
     58 	x = t[ts[1]] * m
     59 
     60 	daily = $amount / x
     61 
     62 	if (total) {
     63 		group = "total"
     64 	} else if (!trim) {
     65 		group = $name
     66 	} else {
     67 		n = split($name, a, "/")
     68 		if (n <= 1) {
     69 			group = $name
     70 		} else {
     71 			group = a[1]
     72 			for (i = 2; i <= trim && i <= n; ++i) {
     73 				group = group "/" a[i]
     74 			}
     75 		}
     76 	}
     77 
     78 	groups[group] += daily
     79 	if (!(group in ordered)) {
     80 		ordered[group] = 1
     81 		order[++oi] = group
     82 	}
     83 }
     84 
     85 END {
     86 	if (status)
     87 		exit 1
     88 	for (i = 1; i <= length(order); ++i) {
     89 		print(order[i], groups[order[i]] * t[output])
     90 	}
     91 }