8 extractDS.px - Extract a single data-source from an RRD-file
12 extractDS.px -i input.rrd -s source_ds -o output.rrd -d destination_ds
16 extractDS.px requires Perl and the included L<Getopt::Long> module, as well as
17 the L<XML::Simple> module.
21 use Getopt::Long ('GetOptions');
22 use XML::Simple (qw(xml_in xml_out));
30 GetOptions ("infile|i=s" => \$InFile,
31 "inds|s=s" => sub { push (@$InDS, $_[1]); },
32 "outfile|o=s" => \$OutFile,
33 "outds|d=s" => sub { push (@$OutDS, $_[1]); })
36 if (!$InFile || !$OutFile || !@$InDS || !@$OutDS)
38 print STDERR "Usage: $0 -i <infile> -s <inds> -o <outfile> -d <outds>\n";
43 print STDERR "Input file does not exist\n";
48 print STDERR "Output file does exist\n";
51 if ((1 + @$InDS) != (1 + @$OutDS))
53 print STDERR "You need the same amount of in- and out-DSes\n";
57 extract_ds ($InFile, $OutFile);
63 # state 0 == searching for DS index
64 # state 1 == parse RRA header
65 # state 2 == parse values
73 if (!defined ($state))
79 # $ds_index->[new_index] = old_index
81 for (my $i = 0; $i < @$InDS; $i++)
92 $out_cache->[$current_index] = $line;
94 elsif ($line =~ m#<name>\s*([^<\s]+)\s*</name>#)
96 # old_index == $current_index
98 for (my $i = 0; $i < @$InDS; $i++)
100 next if ($ds_index->[$i] >= 0);
102 if ($1 eq $InDS->[$i])
104 $line =~ s#<name>\s*([^<\s]+)\s*</name>#<name> $OutDS->[$i] </name>#;
105 $ds_index->[$i] = $current_index;
110 $out_cache->[$current_index] .= $line;
112 elsif ($line =~ m#</ds>#)
114 $out_cache->[$current_index] .= $line;
116 elsif ($line =~ m#<rra>#)
118 # Print out all the DS definitions we need
119 for (my $new_index = 0; $new_index < @$InDS; $new_index++)
121 my $old_index = $ds_index->[$new_index];
122 print $fh $out_cache->[$old_index];
125 # Clear the cache - it's used in state1, too.
126 for (my $i = 0; $i <= $current_index; $i++)
128 $out_cache->[$i] = '';
135 elsif ($current_index == -1)
137 # Print all the lines before the first DS definition
142 # Something belonging to a DS-definition
143 $out_cache->[$current_index] .= $line;
148 if ($line =~ m#<ds>#)
151 $out_cache->[$current_index] .= $line;
153 elsif ($line =~ m#</cdp_prep>#)
155 # Print out all the DS definitions we need
156 for (my $new_index = 0; $new_index < @$InDS; $new_index++)
158 my $old_index = $ds_index->[$new_index];
159 print $fh $out_cache->[$old_index];
163 for (my $i = 0; $i <= $current_index; $i++)
165 $out_cache->[$i] = '';
171 elsif ($line =~ m#<database>#)
176 elsif ($current_index == -1)
178 # Print all the lines before the first DS definition
184 # Something belonging to a DS-definition
185 $out_cache->[$current_index] .= $line;
190 if ($line =~ m#</database>#)
202 if ($line =~ m#(<!-- .*? -->)#)
209 while ($line =~ m#<v>\s*([^<\s]+)\s*</v>#g)
215 for (my $new_index = 0; $new_index < @$InDS; $new_index++)
217 my $old_index = $ds_index->[$new_index];
218 $output .= '<v> ' . $values[$old_index] . ' </v> ';
220 $output .= "</row>\n";
233 my $out_file = shift;
238 open ($in_fh, '-|', 'rrdtool', 'dump', $in_file) or die ("open (rrdtool): $!");
239 # open ($out_fh, '|-', 'rrdtool', 'restore', '-', $out_file) or die ("open (rrdtool): $!");
242 while (my $line = <$in_fh>)
244 handle_line ($out_fh, $line);
253 Florian octo Forster E<lt>octo at verplant.orgE<gt>