-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathrel
executable file
·89 lines (69 loc) · 2.21 KB
/
rel
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
#!/usr/bin/env perl
# This program is part of Aspersa (http://code.google.com/p/aspersa/)
=pod
=head1 NAME
rel - Make each number in a line of text relative to the previous matching line.
=head1 SYNOPSIS
Given a file with some lines of text that follow a repeated pattern, including
numbers,
rel /path/to/file.txt
For example, if the text is this:
Mutex spin waits 0, rounds 99584819933, OS waits 437663963
RW-shared spins 834337527, OS waits 20258150; RW-excl spins 1769749834
Mutex spin waits 0, rounds 99591465498, OS waits 437698122
RW-shared spins 834352175, OS waits 20259032; RW-excl spins 1769762980
The output will be
Mutex spin waits 0, rounds 99584819933, OS waits 437663963
RW-shared spins 834337527, OS waits 20258150; RW-excl spins 1769749834
Mutex spin waits 0, rounds 6645565, OS waits 34159
RW-shared spins 14648, OS waits 882; RW-excl spins 13146
=head1 AUTHOR
Baron Schwartz
=cut
use strict;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
use constant MKDEBUG => $ENV{MKDEBUG};
my $file = shift @ARGV || '-';
my $fh;
if ( $file eq '-' ) {
$fh = *STDIN;
}
else {
open $fh, "<", $file or die "Cannot open $file: $OS_ERROR";
}
my @line_patterns;
my %last_match;
my %printf_for;
while ( my $line = <$fh> ) {
MKDEBUG && print "read: $line\n";
my $matched = 0;
foreach my $pat ( @line_patterns ) {
MKDEBUG && print "trying to match: $pat\n";
if ( my @vals = $line =~ m/$pat/ ) {
MKDEBUG && print "matches\n";
$matched = 1;
my @last_vals = @{ $last_match{$pat} };
my @offset_vals;
for my $i ( 0..$#vals ) {
$offset_vals[$i] = $vals[$i] - $last_vals[$i];
}
$last_match{$pat} = \@vals;
printf $printf_for{$pat}, @offset_vals;
last;
}
}
if ( !$matched ) {
my $new_pat = $line;
$new_pat =~ s/\d+/(\\d+)/g;
my @vals = $line =~ m/$new_pat/;
MKDEBUG && print "new pattern: $new_pat: @vals\n";
push @line_patterns, $new_pat;
(my $printf_pat = $line ) =~ s/\d+/%d/g;
$printf_for{$new_pat} = $printf_pat;
$last_match{$new_pat} = \@vals;
print $line;
}
}
close $fh or warn "Cannot close $file: $OS_ERROR";
exit;