计算 bash/perl 中的时间戳(带关键字)

Calculate timestamps in bash/perl (with keywords)

在我公司,有不同的客户位置"city-01-r-01"和"city-02-r-01"等等。因此,如果无法到达该位置,监控软件会生成状态为 "UNKNOWN" 或 "CRITICAL" 的时间戳。当该位置再次可达时,状态显示为 "OK"。我需要计算无法访问该位置的持续时间。

监控软件为所有客户位置生成此单个文件(.txt 格式),格式如下:

我需要从 .txt 文件中提取上述信息并计算每个位置的不可达性。

我的输出应该是另一个 .txt 文件,格式如下: (脚本可以是 bash 或 perl 或任何其他脚本语言)

我今天在谷歌上搜索了一下,发现我需要使用 IFS(用于逐行阅读)和 while/do 循环来实现这一点。但是,我不确定如何实现结果。

有很多方法可以用 perl、python、SQLite、C、C++、java、tcl、bash...这里是 GNU awk,用于文本文件处理的 GNU 瑞士刀:

$ cat csv2ts.awk
BEGIN { FS = ";" }
{
    t = ;
    gsub(/[-:]/, " ", t);
    t = mktime(t);
}
 == "UNKNOWN" ||  == "CRITICAL" { c[] = t }
 == "OK" {
    d = t - c[];
    printf("%s was unreachable for %d (minutes) %d (seconds) on %s (date)\n",
           , d / 60, d % 60, strftime("%F", t));
}
$ awk -f csv2ts.awk data.csv > data.txt
$ cat data.txt
city-01-r-01 was unreachable for 14 (minutes) 55 (seconds) on 2015-08-02 (date)
city-02-r-01 was unreachable for 5 (minutes) 59 (seconds) on 2015-08-03 (date)

awk 脚本存储在文件 csv2ts.awk 中,您的原始数据在 data.csv 中,输出结果在 data.txt 中。 awk 脚本使用';'作为字段分隔符 (FS = ";")。它使用第一个字段 (gsubmktime) 计算每条记录的时间戳(以秒为单位)。它构建了一个由客户位置(字段#2)索引的时间戳数组(c)。事件日期是使用 strftime 根据第二个事件 (OK) 的时间戳计算得出的。剩下的应该很容易理解了。

请注意您的问题未明确说明:

  • C市的记录在文件中是连续的吗?
  • 您希望日期的确切输出格式是什么?
  • 当不可访问时间跨过天数边界时会发生什么?
  • 如果对于给定的位置,事件的顺序不是“未知、正常”或“严重”、“正常”,而是其他任何情况,例如“正常”、“正常”或“未知、严重”?
  • 如果对于给定位置,第一个事件正常怎么办?
  • 如果对于给定位置,最后一个事件不正常怎么办?

如果您完成规范,调整 awk 脚本应该相当容易。

使用 Perl 非常简单 Time::Piece and Time::Seconds

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use Time::Piece;

my %outages;

my $time_format = '%Y-%m-%d %H:%M:%S';

while (<DATA>) {
  chomp;
  my ($timestamp, $city, $status) = split /;/;

  my $time = Time::Piece->strptime($timestamp, $time_format);

  if ($status ne 'OK') {
    $outages{$city} = $time;
  } else { # status is now ok
    my $duration = $time - $outages{$city};
    say "city $city was unreachable for ",
        $duration->pretty, ' on ', $outages{$city}->date;
  }
}

__END__
2015-08-02 07:18:30;city-01-r-01;UNKNOWN
2015-08-02 07:33:25;city-01-r-01;OK
2015-08-03 12:56:50;city-02-r-01;CRITICAL
2015-08-03 13:02:49;city-02-r-01;OK

(为简单起见,我将数据放在 DATA 文件句柄中。修复它以从外部文件读取数据留作 reader 的练习。)