diff options
Diffstat (limited to 'src/current/tools/csvi')
-rwxr-xr-x | src/current/tools/csvi | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/current/tools/csvi b/src/current/tools/csvi new file mode 100755 index 0000000..08d80e2 --- /dev/null +++ b/src/current/tools/csvi @@ -0,0 +1,124 @@ +#!/usr/bin/awk -f +# +# Performs interpolation for columns in a CSV and outputs the result +# +# 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() } |