timeseries/tsfilter

100 lines
1.9 KiB
Perl
Executable File

#!/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";
}
}