-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwgrep.pl
More file actions
166 lines (154 loc) · 6.11 KB
/
wgrep.pl
File metadata and controls
166 lines (154 loc) · 6.11 KB
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
#!/usr/bin/perl
#
# wgrep.pl - windowed grep utility
#
# Change Log
#----------------------------------------------------------------
# 13/11/2006 - Goran Script Created
#
use strict;
use IO::File;
use IO::Handle;
my ($before,$after,$show_stars,$show_nums,$sep,$show_fname);
my ($show_sep,$arg,$file,$regexp,$lnum,$fhandle,$nbef,$naft);
my ($matched,$matched2,@line_buf,@temp,$fh,$ret);
$before = 3; $after = 3; # default window size
$show_stars = 0;
$show_nums = 0;
$sep = "**********\n";
$show_fname = 1;
$show_sep = 1;
# loop until an argument doesn't begin with a "-"
while ($ARGV[0] =~ /^-(\w)(.*)/) {
$arg = $1; # $arg holds the option letter
if ($arg eq "s") { $show_stars = 1; }
elsif ($arg eq "n") { $show_nums = 1; }
elsif ($arg eq "m") { $show_fname = 0; }
elsif ($arg eq "d") { $show_sep = 0; }
elsif ($arg eq "w") {
# parse 2nd matched section at colon
@temp=split(/:/,$2);
$before = $temp[0] if $temp[0] ne '';
$after = $temp[1] if $temp[1] ne '';
}
elsif ($arg eq "p") {
$before = 0;
$after = 0;
$show_sep = 0; }
elsif ($arg eq "W") {
$before = 0;
$after = 0;
}
elsif ($arg eq "h") { &usage(""); }
else { &usage("wgrep: invalid option: $ARGV[0]");
} # end of if command
shift; # go on to next argument
} # end of foreach loop
&usage("wgrep: missing regular expression") if ! $ARGV[0];
$regexp = $ARGV[0];
shift;
$regexp =~ s,/,\\/,g; # "/" --> "\/"
# if no files are specified, use standard input
if (! @ARGV[0]) { @ARGV[0] = "STDIN"; }
LOOP:
foreach $file (@ARGV) { # loop over file list
if ($file eq "STDIN") {
$fh=new IO::Handle;
$ret=$fh->fdopen(fileno(STDIN),"r");
die "Can't open STDIN." unless $ret;
}
else {
$fh = new IO::File "$file", "r";
if (! defined $fh) {
print STDERR "Can't open file $file; skipping it.\n";
next LOOP; # jump to LOOP label
}
}
$lnum = 0;
$nbef = 0; $naft = 0;
$matched = 0; $matched2 = 0;
&clear_buf(0) if $before > 0;
while (<$fh>) { # loop over the lines in the file
++$lnum; # increment line number
if ($matched) { # we're printing the match window
if ($_ =~ /$regexp/) { # if current line matches pattern:
$naft = 0; # reset the after window count,
&print_info(1); # print preliminary stuff,
print $_; # and print the line
}
else { # current line does not match
if ($after > 0 && ++$naft <= $after) {
# print line anyway if still in the after window
&print_info(0); print $_;
}
else { # after window is done
$matched = 0; # no longer in a match
$naft = 0; # reset the after window count
# save line in before buffer for future matches
push(@line_buf, $_); $nbef++;
} # end else not in after window
} # end else curr. line not a match
} # end if we're in a match
else { # we're still looking for a match
if ($_ =~ /$regexp/) { # we found one
$matched = 1; # so set match flag
# print file and/or section separator(s)
print $sep if $matched2 && $nbef > $before && $show_sep && $show_fname;
print "********** $file **********\n" if ! $matched2++ && $show_fname;
# print and clear out before buffer and reset before counter
&clear_buf(1) if $before > 0; $nbef = 0;
&print_info(1);
print $_; # print current line
}
elsif ($before > 0) {
# pop off oldest line in before buffer & add current line
shift(@line_buf) if $nbef >= $before;
push(@line_buf,$_); $nbef++;
} # end elseif before window is nonzero
} # end else not in a match
} # end while loop over lines in this file
$fh->close;
} # end foreach loop over list of files
exit; # end of script proper
# subroutines #
sub print_info {
print $_[0] ? "* " : " " if $show_stars;
printf "%4d ", $lnum if $show_nums;
} # end subroutine print_info
sub clear_buf {
# argument says whether to print before window or not
my ($i,$j,$print_flag);
$print_flag = $_[0];
$i = 0; $j = 0;
if ($print_flag) {
# if we're printing line numbers, fiddle with the
# counter to account for the before window
if ($show_nums) {
$lnum -= ($#line_buf + 1);
}
while ($j <= $#line_buf) { # print before window
&print_info(0);
print $line_buf[$j++];
$lnum++ if $show_nums;
} # end while
} # end if print_flag
@line_buf = (); # clear line_buf array
} # end subroutine clear_buf
sub usage {
# optional argument is an additional message line
print STDERR $_[0],"\n" if $_[0];
print STDERR "Usage: wgrep [-n] [-w[B][:A] | -W] ";
print STDERR "[-d] [-p] [-s] [-m] regexp file(s)\n";
print STDERR " -n = number lines\n";
print STDERR " -s = mark matched lines with asterisks\n";
print STDERR " -wB:A = display B lines before and A lines after\n";
print STDERR " each matched line [both default to 3]\n";
print STDERR " -W = suppress window; equivalent to -w0:0\n";
print STDERR " -d = suppress separation lines between sections\n";
print STDERR " -m = suppress file name header lines\n";
print STDERR " -p = plain mode: equivalent to -W -d\n";
print STDERR " -h = print this help message and exit\n";
print STDERR "Note: If present, -h prevails; otherwise, the rightmost\n";
print STDERR " option wins in the case of contradictions.\n";
exit;
}