-
Notifications
You must be signed in to change notification settings - Fork 30
/
parse.pl
177 lines (158 loc) · 4.8 KB
/
parse.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#! c:\perl\bin\perl.exe
#-----------------------------------------------------------
# parse.pl - parse an event file containing events in TLN (ie,
# 5-field) format; output goes to STDOUT, can redirect to a
# file.
#
# Change History:
# 20200426 - modified date/time output format to be IAW RFC 3339 profile for ISO 8601
# 20130417 - added option to list events oldest first;
# 20110523 - modified time module to Time::Local
# 20110511 - added csv output option
# 20090610 - added command line options, date range parsing
#
# copyright 2020 Quantum Analytics Research, LLC
# Author: H. Carvey, keydet89@yahoo.com
#-----------------------------------------------------------
use strict;
use Getopt::Long;
use Time::Local;
my %config = ();
Getopt::Long::Configure("prefix_pattern=(-|\/)");
GetOptions(\%config, qw(file|f=s range|r=s csv|c old|o zone|z=i help|?|h));
if ($config{help} || ! %config) {
_syntax();
exit 1;
}
# Get the filename
die "You must include a filename.\n" unless ($config{file});
die "File not found.\n" unless (-e $config{file});
# Hash to hold values
my %tl;
# Range values (if used)
my ($epoch1,$epoch2);
# Check for ranges
if ($config{range}) {
my ($dt1,$dt2) = split(/-/,$config{range});
my ($m1,$d1,$y1) = split(/\//,$dt1);
my $first = $y1.$m1.$d1;
die "Invalid date. Input DD/MM/YYYY.\n" if (($d1 < 1 || $d1 > 31) || ($m1 < 1 || $m1 > 12));
my ($m2,$d2,$y2) = split(/\//,$dt2);
my $last = $y2.$m2.$d2;
if ($first <= $last) {
$epoch1 = getEpoch($y1,$m1,$d1,0,0,0);
$epoch2 = getEpoch($y2,$m2,$d2,23,59,59);
# print gmtime($epoch1)."\n";
# print gmtime($epoch2)."\n";
}
else {
# Second date in the range is smaller than the first, so we just
# reverse them
$epoch1 = getEpoch($y2,$m2,$d2,23,59,59);
$epoch2 = getEpoch($y1,$m1,$d1,0,0,0);
}
}
open(FH,"<",$config{file}) || die "Could not open $config{file}:$!\n";
while(<FH>) {
chomp;
my ($t, $rest) = (split(/\|/,$_,2))[0,1];
if ($config{range}) {
push(@{$tl{$t}},$rest) if ($t > $epoch1 && $t < $epoch2);
}
else {
push(@{$tl{$t}},$rest);
}
}
close(FH);
if ($config{csv}) {
if ($config{old}) {
foreach my $i (sort {$a <=> $b} keys %tl) {
my $csvtime = getDateFromEpoch($i);
# my $csvtime = gmtime($i);
my @events = uniq(@{$tl{$i}});
foreach my $n (@events) {
my ($type,$sys,$user,$desc) = split(/\|/,$n,4);
eval {
print $csvtime."Z,".$type.",".$sys.",".$user.",".$desc."\n";
};
}
}
}
else {
foreach my $i (reverse sort {$a <=> $b} keys %tl) {
my $csvtime = getDateFromEpoch($i);
# my $csvtime = gmtime($i);
my @events = uniq(@{$tl{$i}});
foreach my $n (@events) {
my ($type,$sys,$user,$desc) = split(/\|/,$n,4);
eval {
print $csvtime."Z,".$type.",".$sys.",".$user.",".$desc."\n";
};
}
}
}
}
else {
if ($config{old}) {
foreach my $i (sort {$a <=> $b} keys %tl) {
print getDateFromEpoch($i)."Z\n";
my @events = uniq(@{$tl{$i}});
foreach my $n (@events) {
my ($type,$sys,$user,$desc) = split(/\|/,$n,4);
eval {
printf " %-8s %-16s $user - $desc\n",$type,$sys;
};
}
print "\n";
}
}
else {
foreach my $i (reverse sort {$a <=> $b} keys %tl) {
print getDateFromEpoch($i)."Z\n";
my @events = uniq(@{$tl{$i}});
foreach my $n (@events) {
my ($type,$sys,$user,$desc) = split(/\|/,$n,4);
eval {
printf " %-8s %-16s $user - $desc\n",$type,$sys;
};
}
print "\n";
}
}
}
sub getEpoch {
my ($yy,$mm,$dd,$hr,$min,$sec) = @_;
my $epoch = timegm($sec,$min,$hr,$dd,$mm - 1,$yy);
return $epoch;
}
# ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time)
sub getDateFromEpoch {
my $epoch = shift;
my ($sec,$min,$hour,$mday,$mon,$year) = gmtime($epoch);
my $fmt = sprintf("%04d-%02d-%02d %02d:%02d:%02d",(1900 + $year),($mon + 1),$mday,$hour,$min,$sec);
return $fmt."Z";
}
# remove duplicate lines from an array, return an array
sub uniq {
return keys %{{ map { $_ => 1 } @_ }};
}
sub _syntax {
print<< "EOT";
parse [option]
Parse contents event file to produce a timeline; output goes to STDOUT
-f file........event file to be parsed; must be 5-field TLN
format
-c ............CSV output format (for opening in Excel), time in
YYYY-MM-DD hh:mm:ss format (RFC 3339 profile for ISO 8601)
-o ............sort showing oldest events first
-r range ......range of dates, MM/DD/YYYY-MM/DD/YYYY format; time range of
00:00:00 is automatically added to the first date, and
23:59:59 is automatically added to the second date.
-h ............Help (print this information)
Ex: C:\\>parse -f events\.txt -o > tln\.txt
C:\\>parse -f events\.txt -r 02/12/2008-03/16/2008 > tln\.txt
C:\\>parse -f events\.txt -c > tln\.csv
**All times printed as GMT/UTC
copyright 2020 Quantum Analytics Research, LLC
EOT
}