diff options
Diffstat (limited to 'build-aux/csvi')
-rwxr-xr-x | build-aux/csvi | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/build-aux/csvi b/build-aux/csvi new file mode 100755 index 0000000..01e7204 --- /dev/null +++ b/build-aux/csvi @@ -0,0 +1,138 @@ +#!/usr/bin/awk -f +# +# Performs interpolation for columns in a CSV and outputs the result +# +# Copyright (C) 2016 R-T Specialty, LLC. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Configurable values (use -vname=value from command line): +# step - use predeterminated step instead of calculating from first two rows +## + +function storeline() +{ + for ( i = 1; i <= hlen; i++ ) { + prev[i] = $i + } +} + +function clearline() +{ + for ( i = 1; i <= hlen; i++ ) { + prev[i] = 0 + } +} + +function getprev() +{ + for ( i = 1; i <= hlen; i++ ) { + $i = prev[i] + } +} + + +function interpolate() +{ + lastval = prev[1] + + curval = $1 + diff = curval - lastval + + # does this value fall in line with the requested step? + if ( diff == step ) + { + storeline() + + # we're good; continue + print + next + } + + # if we do not yet have a value large enough to reach our step, then continue + # until we do (do not store this line) + n = int( diff / step ) + if ( n <= 0 ) { + next + } + + # determine interpolation values + for ( i = 2; i <= hlen; i++ ) { + ival[i] = ( ( $i - prev[i] ) / n ) + } + + getprev() + + # let us interpolate values that are divisible by the step + do + { + # increase the last value by our step + $1 += step + + # interpolate each column value (notice that we skip the first column, which + # was handled directly above) + for ( i = 2; i <= hlen; i++ ) { + $i += ival[i] + } + + # print the new line + print + } while ( ( diff -= step ) > 0 ) + + # anything remaining does not fit into our step and will be ignored; we'll + # continue with our next step at the next line + + # consider this to be our last line + storeline() +} + + +BEGIN { + # the first row of the CSV is the header representing the column identifiers + getline + hlen = split( $0, header, /,/ ) + + # output the header + print $0 + + # delimit fields by commas (the field separator for CSVs); note that this + # won't work properly if strings contain commas + FS = OFS = "," + + clearline() + getline + + # if no step was provided, then calculate one based on the first two rows + if ( step == 0 ) { + # output the first row, which does not need to be interpolated + print + + # compute the step + vala = $1 + getline + valb = $1 + step = valb - vala + + # since the second line is used to determine the step, then it must match the + # step and therefore is good to output + print + + # begin. + storeline() + } +} + + +# for each row +{ interpolate() } |