#!/usr/bin/perl -w use strict; use TimeSeries; use Getopt::Long; use Pod::Usage; use POSIX qw(strftime); =head1 NAME tsfilter - filter a time series in column format =head1 SYNOPSIS tsfilter [--start time] [--end time ] [--time_t] [--tsv] [file ...] =head1 DESCRIPTION ... The --time_t option specifies that the timestamps are in seconds since the epoch. Otherwise they are parsed by add_timestring function (which in turn uses the parse_date function of the HTTP::Date module). =cut my $time_t =0; my $tsv = 0; my $start; my $end; GetOptions('start=s' => \$start, 'end=s' => \$end, 'time_t' => \$time_t, 'tsv' => \$tsv, ) or pod2usage(verbose => 0); my $sep = $tsv ? qr/\t/ : qr/\s+/; if (defined $start) { if ($start =~ /^\d+$/) { # already numeric } elsif ($start =~ /^([-+]\d+)([dhms])$/) { $start = time() + $1 * ($2 eq 'd' ? 86400 : $2 eq 'h' ? 3600 : $2 eq 'm' ? 60 : 1); } else { $start = str2time($start); } } else { $start = '-Inf'; } if (defined $end) { if ($end =~ /^\d+$/) { # already numeric } elsif ($end =~ /^([-+]\d+)([dhms])$/) { $end = time() + $1 * ($2 eq 'd' ? 86400 : $2 eq 'h' ? 3600 : $2 eq 'm' ? 60 : 1); } else { $end = str2time($end); } } else { $end = 'Inf'; } binmode STDOUT, ':raw'; my $ts = TimeSeries->new(); while (<>) { chomp; my @legend = split($sep); shift @legend; # first must be for timestamp $ts->legend(@legend); last; } while (<>) { chomp; my ($timestamp, @values) = split($sep); if ($time_t) { $ts->add($timestamp, @values); } else { $ts->add_timestring($timestamp, @values); } } print join("\t", "date", $ts->legend), "\n"; for my $dp (@{ $ts->{data} }) { if ($dp->[0] >= $start && $dp->[0] <= $end) { if ($time_t) { print $dp->[0]; } else { print strftime("%Y-%m-%dT%H:%M:%S%z", localtime($dp->[0])); } for my $v (@{$dp->[1]}) { print "\t$v"; } print "\n"; } }