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');
29 GetOptions ("infile|i=s" => \$InFile,
30 "inds|s=s" => sub { push (@$InDS, $_[1]); },
31 "outfile|o=s" => \$OutFile,
32 "outds|d=s" => sub { push (@$OutDS, $_[1]); })
35 if (!$InFile || !$OutFile || !@$InDS || !@$OutDS)
37 print STDERR "Usage: $0 -i <infile> -s <inds> -o <outfile> -d <outds>\n";
42 print STDERR "Input file does not exist\n";
47 print STDERR "Output file does exist\n";
50 if ((1 + @$InDS) != (1 + @$OutDS))
52 print STDERR "You need the same amount of in- and out-DSes\n";
56 extract_ds ($InFile, $OutFile);
62 # state 0 == searching for DS index
63 # state 1 == parse RRA header
64 # state 2 == parse values
72 if (!defined ($state))
78 # $ds_index->[new_index] = old_index
80 for (my $i = 0; $i < @$InDS; $i++)
91 $out_cache->[$current_index] = $line;
93 elsif ($line =~ m#<name>\s*([^<\s]+)\s*</name>#)
95 # old_index == $current_index
97 for (my $i = 0; $i < @$InDS; $i++)
99 next if ($ds_index->[$i] >= 0);
101 if ($1 eq $InDS->[$i])
103 $line =~ s#<name>\s*([^<\s]+)\s*</name>#<name> $OutDS->[$i] </name>#;
104 $ds_index->[$i] = $current_index;
109 $out_cache->[$current_index] .= $line;
111 elsif ($line =~ m#</ds>#)
113 $out_cache->[$current_index] .= $line;
115 elsif ($line =~ m#<rra>#)
117 # Print out all the DS definitions we need
118 for (my $new_index = 0; $new_index < @$InDS; $new_index++)
120 my $old_index = $ds_index->[$new_index];
121 print $fh $out_cache->[$old_index];
124 # Clear the cache - it's used in state1, too.
125 for (my $i = 0; $i <= $current_index; $i++)
127 $out_cache->[$i] = '';
134 elsif ($current_index == -1)
136 # Print all the lines before the first DS definition
141 # Something belonging to a DS-definition
142 $out_cache->[$current_index] .= $line;
147 if ($line =~ m#<ds>#)
150 $out_cache->[$current_index] .= $line;
152 elsif ($line =~ m#</cdp_prep>#)
154 # Print out all the DS definitions we need
155 for (my $new_index = 0; $new_index < @$InDS; $new_index++)
157 my $old_index = $ds_index->[$new_index];
158 print $fh $out_cache->[$old_index];
162 for (my $i = 0; $i <= $current_index; $i++)
164 $out_cache->[$i] = '';
170 elsif ($line =~ m#<database>#)
175 elsif ($current_index == -1)
177 # Print all the lines before the first DS definition
183 # Something belonging to a DS-definition
184 $out_cache->[$current_index] .= $line;
189 if ($line =~ m#</database>#)
201 if ($line =~ m#(<!-- .*? -->)#)
208 while ($line =~ m#<v>\s*([^<\s]+)\s*</v>#g)
214 for (my $new_index = 0; $new_index < @$InDS; $new_index++)
216 my $old_index = $ds_index->[$new_index];
217 $output .= '<v> ' . $values[$old_index] . ' </v> ';
219 $output .= "</row>\n";
232 my $out_file = shift;
237 open ($in_fh, '-|', 'rrdtool', 'dump', $in_file) or die ("open (rrdtool): $!");
238 open ($out_fh, '|-', 'rrdtool', 'restore', '-', $out_file) or die ("open (rrdtool): $!");
240 while (my $line = <$in_fh>)
242 handle_line ($out_fh, $line);
251 Florian octo Forster E<lt>octo at verplant.orgE<gt>