1File::Finder(3) User Contributed Perl Documentation File::Finder(3)
2
3
4
6 File::Finder - nice wrapper for File::Find ala find(1)
7
9 use File::Finder;
10 ## simulate "-type f"
11 my $all_files = File::Finder->type('f');
12
13 ## any rule can be extended:
14 my $all_files_printer = $all_files->print;
15
16 ## traditional use: generating "wanted" subroutines:
17 use File::Find;
18 find($all_files_printer, @starting_points);
19
20 ## or, we can gather up the results immediately:
21 my @results = $all_files->in(@starting_points);
22
23 ## -depth and -follow are noted, but need a bit of help for find:
24 my $deep_dirs = File::Finder->depth->type('d')->ls->exec('rmdir','{}');
25 find($deep_dirs->as_options, @places);
26
28 "File::Find" is great, but constructing the "wanted" routine can
29 sometimes be a pain. This module provides a "wanted"-writer, using
30 syntax that is directly mappable to the find command's syntax.
31
32 Also, I find myself (heh) frequently just wanting the list of names
33 that match. With "File::Find", I have to write a little accumulator,
34 and then access that from a closure. But with "File::Finder", I can
35 turn the problem inside out.
36
37 A "File::Finder" object contains a hash of "File::Find" options, and a
38 series of steps that mimic find's predicates. Initially, a
39 "File::Finder" object has no steps. Each step method clones the
40 previous object's options and steps, and then adds the new step,
41 returning the new object. In this manner, an object can be grown, step
42 by step, by chaining method calls. Furthermore, a partial sequence can
43 be created and held, and used as the head of many different sequences.
44
45 For example, a step sequence that finds only files looks like:
46
47 my $files = File::Finder->type('f');
48
49 Here, "type" is acting as a class method and thus a constructor. An
50 instance of "File::Finder" is returned, containing the one step to
51 verify that only files are selected. We could use this immediately as
52 a "File::Find::find" wanted routine, although it'd be uninteresting:
53
54 use File::Find;
55 find($files, "/tmp");
56
57 Calling a step method on an existing object adds the step, returning
58 the new object:
59
60 my $files_print = $files->print;
61
62 And now if we use this with "find", we get a nice display:
63
64 find($files_print, "/tmp");
65
66 Of course, we didn't really need that second object: we could have
67 generated it on the fly:
68
69 find($files->print, "/tmp");
70
71 "File::Find" supports options to modify behavior, such as depth-first
72 searching. The "depth" step flags this in the options as well:
73
74 my $files_depth_print = $files->depth->print;
75
76 However, the "File::Finder" object needs to be told explictly to
77 generate an options hash for "File::Find::find" to pass this
78 information along:
79
80 find($files_depth_print->as_options, "/tmp");
81
82 A "File::Finder" object, like the find command, supports AND, OR, NOT,
83 and parenthesized sub-expressions. AND binds tighter than OR, and is
84 also implied everywhere that it makes sense. Like find, the predicates
85 are computed in a "short-circuit" fashion, so that a false to the left
86 of the (implied) AND keeps the right side from being evaluated,
87 including entire parenthesized subexpressions. Similarly, if the left
88 side of an OR is false, the right side is evaluated, and if the left
89 side of the OR is true, the right side is skipped. Nested parens are
90 handled properly. Parens are indicated with the rather ugly "left" and
91 "right" methods:
92
93 my $big_or_old_files = $files->left->size("+50")->or->atime("+30")->right;
94
95 The parens here correspond directly to the parens in:
96
97 find somewhere -type f '(' -size +50 -o -atime +30 ')'
98
99 and are needed so that the OR and the implied ANDs have the right
100 nesting.
101
102 Besides passing the constructed "File::Finder" object to
103 "File::Finder::find" directly as a "wanted" routine or an options hash,
104 you can also call "find" implictly, with "in". "in" provides a list of
105 starting points, and returns all filenames that match the criteria.
106
107 For example, a list of all names in /tmp can be generated simply with:
108
109 my @names = File::Finder->in("/tmp");
110
111 For more flexibility, use "collect" to execute an arbitrary block in a
112 list context, concatenating all the results (similar to "map"):
113
114 my %sizes = File::Finder
115 ->collect(sub { $File::Find::name => -s _ }, "/tmp");
116
117 That's all I can think of for now. The rest is in the detailed
118 reference below.
119
120 META METHODS
121 All of these methods can be used as class or instance methods, except
122 "new", which is usually not needed and is class only.
123
124 new Not strictly needed, because any instance method called on a class
125 will create a new object anyway.
126
127 as_wanted
128 Returns a subroutine suitable for passing to "File::Find::find" or
129 "File::Find::finddepth" as the wanted routine. If the object is
130 used in a place that wants a coderef, this happens automatically
131 through overloading.
132
133 as_options
134 Returns a hashref suitable for passing to "File::Find::find" or
135 "File::Find::finddepth" as the options hash. This is necessary if
136 you want the meta-information to carry forward properly.
137
138 in(@starting_points)
139 Calls "File::Find::find($self->as_options, @starting_points)",
140 gathering the results, and returns the results as a list. At the
141 moment, it also returns the count of those items in a scalar
142 context. If that's useful, I'll maintain that.
143
144 collect($coderef, @starting_points)
145 Calls $coderef in a list context for each of the matching items,
146 gathering and concatenating the results, and returning the results
147 as a list.
148
149 my $f = File::Finder->type('f');
150 my %sizes = $f->collect(sub { $File::Find::name, -s _ }, "/tmp");
151
152 In fact, "in" is implemented by calling "collect" with a coderef of
153 just "sub { $File::Find::name }".
154
155 STEPS
156 See File::Finder::Steps.
157
158 SPEED
159 All the steps can have a compile-time and run-time component. As much
160 work is done during compile-time as possible. Runtime consists of a
161 simple linear pass executing a series of closures representing the
162 individual steps (not method calls). It is hoped that this will
163 produce a speed that is within a factor of 2 or 3 of a handcrafted
164 monolithic "wanted" routine.
165
167 File::Finder::Steps, File::Find, find2perl, File::Find::Rule
168
170 Please report bugs to "bug-File-Finder@rt.cpan.org".
171
173 Randal L. Schwartz, <merlyn@stonehenge.com>, with a tip of the hat to
174 Richard Clamp for "File::Find::Rule".
175
177 Copyright (C) 2003,2004 by Randal L. Schwartz, Stonehenge Consulting
178 Services, Inc.
179
180 This library is free software; you can redistribute it and/or modify it
181 under the same terms as Perl itself, either Perl version 5.8.2 or, at
182 your option, any later version of Perl 5 you may have available.
183
184
185
186perl v5.32.0 2020-07-28 File::Finder(3)