File Coverage

blib/lib/App/Greple/line.pm
Criterion Covered Total %
statement 26 40 65.0
branch 0 4 0.0
condition n/a
subroutine 9 10 90.0
pod 0 1 0.0
total 35 55 63.6


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             line - Greple module to produce result by line numbers
4              
5             =head1 SYNOPSIS
6              
7             greple -Mline
8              
9             =head1 DESCRIPTION
10              
11             This module allows you to use line numbers to specify patterns or
12             regions which can be used in B options.
13              
14             =over 7
15              
16             =item B<-L>=I
17              
18             Simply, next command will show 200th line with before/after 10 lines
19             of the file:
20              
21             greple -Mline -L 200 -C10 file
22              
23             If you don't like lines displayed with color, use B<--nocolor> option
24             or set colormap to something do nothing like B<--cm=N>.
25              
26             Multiple lines can be specified by joining with comma:
27              
28             greple -Mline -L 10,20,30
29              
30             It is ok to use B<-L> option multiple times, like:
31              
32             greple -Mline -L 10 -L 20 -L 30
33              
34             But this command produce nothing, because each line definitions are
35             taken as a different pattern, and B prints lines only when all
36             patterns matched. You can relax the condition by C<--need 1> option
37             in such case, then you will get expected result. Next example will
38             display 10th, 20th and 30th lines in different colors.
39              
40             greple -Mline -L 10 -L 20 -L 30 --need 1
41              
42             Range can be specified by colon:
43              
44             greple -Mline -L 10:20
45              
46             You can also specify the step with range. Next command will print
47             all even lines from line 10 to 20:
48              
49             greple -Mline -L 10:20:2
50              
51             Any of them can be omitted. Next commands print all, odd and even
52             lines.
53              
54             greple -Mline -L :: # all lines
55             greple -Mline -L ::2 # odd lines
56             greple -Mline -L 2::2 # even lines
57              
58             If start and end number is negative, they are subtracted from the
59             maxmum line number. If the end number is prefixed by plus (`+') sign,
60             it is summed with start number. Next commands print top and last 10
61             lines respectively.
62              
63             greple -Mline -L :+9 # top 10 lines
64             greple -Mline -L -9: # last 10 lines
65              
66             Next example print all lines of the file, each line in four different
67             colors.
68              
69             greple -Mline -L=1::4 -L=2::4 -L=3::4 -L=4::4 --need 1
70              
71             If forth parameter is given, it describes how many lines is included
72             in that step cycle. For example, next command prints top 3 lines in
73             every 10 lines.
74              
75             greple -Mline -L ::10:3
76              
77             When step count is omitted, forth value is used if available. Next
78             command print every 10 lines in different colors.
79              
80             greple -Mline -L :::10 --ci=A /etc/services
81              
82             =item B=I
83              
84             This notation just define function spec, which can be used in
85             patterns, as well as blocks and regions. Actually, B<-L>=I is
86             equivalent to B<--le> B=I.
87              
88             Next command show patterns found in line number 1000-2000 area.
89              
90             greple -Mline --inside L=1000:+1000 pattern
91              
92             Next command prints all 10 line blocks which include the pattern.
93              
94             greple -Mline --block L=:::10 pattern
95              
96             In this case, however, it is faster and easier to use regex.
97              
98             greple --block '(.*\n){1,10}' pattern
99              
100             =back
101              
102             Using this module, it is impossible to give single C in command
103             line arguments. Use like B<--le=L> to search letter C. You have a
104             file named F? Stop substitution by placing C<--> before the target
105             files.
106              
107             =head1 SEE ALSO
108              
109             L
110              
111             =cut
112              
113             package App::Greple::line;
114              
115 1     1   69268 use v5.14;
  1         11  
116 1     1   5 use warnings;
  1         1  
  1         37  
117              
118 1     1   6 use Carp;
  1         1  
  1         72  
119 1     1   6 use List::Util qw(min max);
  1         2  
  1         99  
120 1     1   697 use Data::Dumper;
  1         6869  
  1         58  
121              
122 1     1   7 use Exporter qw(import);
  1         1  
  1         65  
123             our @EXPORT = qw(&line);
124              
125 1     1   378 use App::Greple::Common;
  1         3  
  1         109  
126 1     1   402 use App::Greple::Regions qw(match_borders borders_to_regions);
  1         3  
  1         154  
127              
128             sub line {
129 0     0 0   my %arg = @_ ;
130 0 0         my $file = delete $arg{&FILELABEL} or die;
131 0           state $target = -1;
132 0           state @lines;
133              
134 0 0         if ($target != \$_) {
135 0           @lines = ([0, 0], borders_to_regions match_borders qr/^/m);
136 0           $target = \$_;
137             }
138              
139 1     1   474 use Getopt::EX::Numbers;
  1         7584  
  1         144  
140 0           my $numbers = Getopt::EX::Numbers->new(min => 1, max => $#lines);
141              
142 0           my @result = do {
143 0           map { [ $lines[$_->[0]]->[0], $lines[$_->[1]]->[1] ] }
144 0           sort { $a->[0] <=> $b->[0] }
145 0           map { $numbers->parse($_)->range }
  0            
146             keys %arg;
147             };
148 0           @result;
149             }
150              
151             1;
152              
153             __DATA__