Mike Gerwitz

Activist for User Freedom

aboutsummaryrefslogtreecommitdiffstats
blob: 08d80e2a4058a49d0fb30518bde89e6a881e80ad (plain)
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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() }