1File::Finder::Steps(3)User Contributed Perl DocumentationFile::Finder::Steps(3)
2
3
4
6 File::Finder::Steps - steps for File::Finder
7
9 ## See File::Finder for normal use of steps
10
11 ## subclassing example:
12 BEGIN {
13 package My::File::Finder;
14 use base File::Finder;
15
16 sub _steps_class { "My::File::Finder::Steps" }
17 }
18 BEGIN {
19 package My::File::Finder::Steps;
20 use base File::Finder::Steps;
21
22 sub bigger_than { # true if bigger than N bytes
23 my $self = shift;
24 my $bytes = shift;
25 return sub {
26 -s > $bytes;
27 }
28 }
29 }
30
31 my $over_1k = My::File::Finder->bigger_than(1024);
32 print "Temp files over 1k:\n";
33 $over_1k->ls->in("/tmp");
34
36 "File::Finder::Steps" provide the predicates being tested for
37 "File::Finder".
38
39 STEPS METHODS
40 These methods are called on a class or instance to add a "step". Each
41 step adds itself to a list of steps, returning the new object. This
42 allows you to chain steps together to form a formula.
43
44 As in find, the default operator is "and", and short-circuiting is
45 performed.
46
47 or Like find's "or".
48
49 left
50 Like a left parenthesis. Used in nesting pairs with "right".
51
52 right
53 Like a right parenthesis. Used in nesting pairs with "left". For
54 example:
55
56 my $big_or_old = File::Finder
57 ->type('f')
58 ->left
59 ->size("+100")->or->mtime("+90")
60 ->right;
61 find($big_or_old->ls, "/tmp");
62
63 You need parens because the "or" operator is lower precedence than
64 the implied "and", for the same reason you need them here:
65
66 find /tmp -type f '(' -size +100 -o -mtime +90 ')' -print
67
68 Without the parens, the -type would bind to -size, and not to the
69 choice of -size or -mtime.
70
71 Mismatched parens will not be found until the formula is used,
72 causing a fatal error.
73
74 begin
75 Alias for "left".
76
77 end Alias for "right".
78
79 not Like find's "!". Prefix operator, can be placed in front of
80 individual terms or open parens. Can be nested, but what's the
81 point?
82
83 # list all non-files in /tmp
84 File::Finder->not->type('f')->ls->in("/tmp");
85
86 true
87 Always returns true. Useful when a subexpression might fail, but
88 you don't want the overall code to fail:
89
90 ... ->left-> ...[might return false]... ->or->true->right-> ...
91
92 Of course, this is the find command's idiom of:
93
94 find .... '(' .... -o -true ')' ...
95
96 false
97 Always returns false.
98
99 comma
100 Like GNU find's ",". The result of the expression (or
101 subexpression if in parens) up to this point is discarded, and
102 execution continues afresh. Useful when a part of the expression
103 is needed for its side effects, but shouldn't affect the rest of
104 the "and"-ed chain.
105
106 # list all files and dirs, but don't descend into CVS dir contents:
107 File::Finder->type('d')->name('CVS')->prune->comma->ls->in('.');
108
109 follow
110 Enables symlink following, and returns true.
111
112 name(NAME)
113 True if basename matches NAME, which can be given as a glob pattern
114 or a regular expression object:
115
116 my $pm_files = File::Finder->name('*.pm')->in('.');
117 my $pm_files_too = File::Finder->name(qr/pm$/)->in('.');
118
119 perm(PERMISSION)
120 Like find's "-perm". Leading "-" means "all of these bits".
121 Leading "+" means "any of these bits". Value is de-octalized if a
122 leading 0 is present, which is likely only if it's being passed as
123 a string.
124
125 my $files = File::Finder->type('f');
126 # find files that are exactly mode 644
127 my $files_644 = $files->perm(0644);
128 # find files that are at least world executable:
129 my $files_world_exec = $files->perm("-1");
130 # find files that have some executable bit set:
131 my $files_exec = $files->perm("+0111");
132
133 type(TYPE)
134 Like find's "-type". All native Perl types are supported. Note
135 that "s" is a socket, mapping to Perl's "-S", to be consistent with
136 find. Returns true or false, as appropriate.
137
138 print
139 Prints the fullname to "STDOUT", followed by a newline. Returns
140 true.
141
142 print0
143 Prints the fullname to "STDOUT", followed by a NUL. Returns true.
144
145 fstype
146 Not implemented yet.
147
148 user(USERNAME|UID)
149 True if the owner is USERNAME or UID.
150
151 group(GROUPNAME|GID)
152 True if the group is GROUPNAME or GID.
153
154 nouser
155 True if the entry doesn't belong to any known user.
156
157 nogroup
158 True if the entry doesn't belong to any known group.
159
160 links( +/- N )
161 Like find's "-links N". Leading plus means "more than", minus
162 means "less than".
163
164 inum( +/- N )
165 True if the inode number meets the qualification.
166
167 size( +/- N [c/k])
168 True if the file size meets the qualification. By default, N is in
169 half-K blocks. Append a trailing "k" to the number to indicate 1K
170 blocks, or "c" to indicate characters (bytes).
171
172 atime( +/- N )
173 True if access time (in days) meets the qualification.
174
175 mtime( +/- N )
176 True if modification time (in days) meets the qualification.
177
178 ctime( +/- N )
179 True if inode change time (in days) meets the qualification.
180
181 exec(@COMMAND)
182 Forks the child process via "system()". Any appearance of "{}" in
183 any argument is replaced by the current filename. Returns true if
184 the child exit status is 0. The list is passed directly to
185 "system", so if it's a single arg, it can contain "/bin/sh" syntax.
186 Otherwise, it's a pre-parsed command that must be found on the
187 PATH.
188
189 Note that I couldn't figure out how to horse around with the
190 current directory very well, so I'm using $_ here instead of the
191 more traditional "File::Find::name". It still works, because we're
192 still chdir'ed down into the directory, but it looks weird on a
193 trace. Trigger "no_chdir" in "find" if you want a traditional find
194 full path.
195
196 my $f = File::Finder->exec('ls', '-ldg', '{}');
197 find({ no_chdir => 1, wanted => $f }, @starting_dirs);
198
199 Yeah, it'd be trivial for me to add a no_chdir method. Soon.
200
201 ok(@COMMAND)
202 Like "exec", but displays the command line first, and waits for a
203 response. If the response begins with "y" or "Y", runs the
204 command. If the command fails, or the response wasn't yes, returns
205 false, otherwise true.
206
207 prune
208 Sets $File::Find::prune, and returns true.
209
210 xdev
211 Not yet implemented.
212
213 newer
214 Not yet implemented.
215
216 eval(CODEREF)
217 Ah yes, the master escape, with extra benefits. Give it a coderef,
218 and it evaluates that code at the proper time. The return value is
219 noted for true/false and used accordingly.
220
221 my $blaster = File::Finder->atime("+30")->eval(sub { unlink });
222
223 But wait, there's more. If the parameter is an object that
224 responds to "as_wanted", that method is automatically called,
225 hoping for a coderef return. This neat feature allows subroutines
226 to be created and nested:
227
228 my $old = File::Finder->atime("+30");
229 my $big = File::Finder->size("+100");
230 my $old_or_big = File::Finder->eval($old)->or->eval($big);
231 my $killer = File::Finder->eval(sub { unlink });
232 my $kill_old_or_big = File::Finder->eval($old_or_big)->ls->eval($killer);
233 $kill_old_or_big->in('/tmp');
234
235 Almost too cool for words.
236
237 depth
238 Like find's "-depth". Sets a flag for "as_options", and returns
239 true.
240
241 ls Like find's "-ls". Performs a "ls -dils" on the entry to "STDOUT"
242 (without forking), and returns true.
243
244 tar Not yet implemented.
245
246 [n]cpio
247 Not yet implemented.
248
249 ffr($ffr_object)
250 Incorporate a "File::Find::Rule" object as a step. Note that this
251 must be a rule object, and not a result, so don't call or pass
252 "in". For example, using "File::Find::Rule::ImageSize" to define a
253 predicate for image files that are bigger than a megapixel in my
254 friends folder, I get:
255
256 require File::Finder;
257 require File::Find::Rule;
258 require File::Find::Rule::ImageSize;
259 my $ffr = File::Find::Rule->file->image_x('>1000')->image_y('>1000');
260 my @big_friends = File::Finder->ffr($ffr)
261 ->in("/Users/merlyn/Pictures/Sorted/Friends");
262
263 contains(pattern)
264 True if the file contains "pattern" (either a literal string
265 treated as a regex, or a true regex object).
266
267 my $plugh_files = File::Finder->type('f')->contains(qr/plugh/);
268
269 Searching is performed on a line-by-line basis, respecting the
270 current value of $/.
271
272 EXTENDING
273 A step consists of a compile-time and a run-time component.
274
275 During the creation of a "File::Finder" object, step methods are called
276 as if they were methods against the slowly-growing "File::Finder"
277 instance, including any additional parameters as in a normal method
278 call. The step is expected to return a coderef (possibly a closure) to
279 be executed at run-time.
280
281 When a "File::Finder" object is being evaluated as the "File::Find"
282 "wanted" routine, the collected coderefs are evaluated in sequence,
283 again as method calls against the "File::Finder" object. No additional
284 parameters are passed. However, the normal "wanted" values are
285 available, such as $_, $File::Find::name, and so on. The "_" pseudo-
286 handle has been set properly, so you can safely use "-X" filetests and
287 "stat" against the pseudo-handle. The routine is expected to return a
288 true/false value, which becomes the value of the step.
289
290 Although a "File::Finder" object is passed both to the compile-time
291 invocation and the resulting run-time invocation, only the "options"
292 self-hash element is properly duplicated through the cloning process.
293 Do not be tempted to add additional self-hash elements without
294 overriding "File::Finder"'s "_clone". Instead, pass values from the
295 compile-time phase to the run-time phase using closure variables, as
296 shown in the synopsis.
297
298 For simplicity, you can also just mix-in your methods to the existing
299 "File::Finder::Steps" class, rather than subclassing both classes as
300 shown above. However, this may result in conflicting implementations
301 of a given step name, so beware.
302
304 File::Finder
305
307 None known yet.
308
310 Randal L. Schwartz, <merlyn@stonehenge.com>
311
313 Copyright (C) 2003,2004 by Randal L. Schwartz, Stonehenge Consulting
314 Services, Inc.
315
316 This library is free software; you can redistribute it and/or modify it
317 under the same terms as Perl itself, either Perl version 5.8.2 or, at
318 your option, any later version of Perl 5 you may have available.
319
320
321
322perl v5.34.0 2021-07-22 File::Finder::Steps(3)