#!/bin/awk -f
# see http://theunixshell.blogspot.de/2014/05/comparing-two-files-using-awk.html
BEGIN {
if(ARGC != 3) {
printf("Usage: %s company_file balance_file\n", ARGV[0])
exit 2
}
# split on dollar sign for easier processing of second file
FS = "$"
}
# Sanitize and filter input first
# We use the NR == FNR idiom to distinguish the two files
# We are also very forgiving when it comes to company names. They just have
# to start with a non-whitespace and cannot contain dollar signs
(NR == FNR && ! /^[^\s\$][^$]*$/) ||
(NR != FNR &&
! /^[^\s\$][^$]*\s+\$[[:digit:]]+\.[[:digit:]]{2}\s+((due)|(payment))$/) {
printf("Formatting error in file '%s', line %d: '%s'\n", FILENAME, FNR,
$0) > "/dev/stderr"
next
}
# both files: Retrieve name of company by removing trailing whitespace
{
company = gensub(/\s+$/, "", 1, $1)
}
# company_file: Initializes balance array in case a company made no entries in
# the balance file.
# Aborts processing of this line at the end so that we don't have to check for
# NR != FNR in the rest of the script
NR == FNR {
balance[company] = 0.
next
}
# balance_file: Retrieve amount of money.
# Note that $2 contains everything up to the end of the file but strtonum will
# abort without error on the first non-digit
# We also check for companies not defined in company_file and skip them
{
money = strtonum($2)
if(! company in balance) {
printf("Undefined company '%s' in file '%s', line '%d'\n", company,
FILENAME, FNR) > "/dev/stderr"
next
}
}
# add or subtract money depending on instruction
/due$/ {
balance[company] -= money
}
/payment$/ {
balance[company] += money
}
# print balance
END {
for (company in balance)
printf("%s\t$%.2f\n", company, balance[company])
}
Comments
0 B
|👍
/👎
0 B
|👍
/👎