|
|
| |
File::Finder::Steps(3) |
User Contributed Perl Documentation |
File::Finder::Steps(3) |
File::Finder::Steps - steps for File::Finder
## See File::Finder for normal use of steps
## subclassing example:
BEGIN {
package My::File::Finder;
use base File::Finder;
sub _steps_class { "My::File::Finder::Steps" }
}
BEGIN {
package My::File::Finder::Steps;
use base File::Finder::Steps;
sub bigger_than { # true if bigger than N bytes
my $self = shift;
my $bytes = shift;
return sub {
-s > $bytes;
}
}
}
my $over_1k = My::File::Finder->bigger_than(1024);
print "Temp files over 1k:\n";
$over_1k->ls->in("/tmp");
"File::Finder::Steps" provide the predicates
being tested for "File::Finder".
These methods are called on a class or instance to add a "step". Each
step adds itself to a list of steps, returning the new object. This allows you
to chain steps together to form a formula.
As in find, the default operator is "and", and
short-circuiting is performed.
- or
- Like find's "or".
- left
- Like a left parenthesis. Used in nesting pairs with
"right".
- right
- Like a right parenthesis. Used in nesting pairs with
"left". For example:
my $big_or_old = File::Finder
->type('f')
->left
->size("+100")->or->mtime("+90")
->right;
find($big_or_old->ls, "/tmp");
You need parens because the "or" operator is lower
precedence than the implied "and", for the same reason you
need them here:
find /tmp -type f '(' -size +100 -o -mtime +90 ')' -print
Without the parens, the -type would bind to -size, and not to
the choice of -size or -mtime.
Mismatched parens will not be found until the formula is used,
causing a fatal error.
- begin
- Alias for "left".
- end
- Alias for "right".
- not
- Like find's "!". Prefix operator,
can be placed in front of individual terms or open parens. Can be nested,
but what's the point?
# list all non-files in /tmp
File::Finder->not->type('f')->ls->in("/tmp");
- true
- Always returns true. Useful when a subexpression might fail, but you don't
want the overall code to fail:
... ->left-> ...[might return false]... ->or->true->right-> ...
Of course, this is the find command's idiom of:
find .... '(' .... -o -true ')' ...
- false
- Always returns false.
- comma
- Like GNU find's ",". The result of the expression (or
subexpression if in parens) up to this point is discarded, and execution
continues afresh. Useful when a part of the expression is needed for its
side effects, but shouldn't affect the rest of the "and"-ed
chain.
# list all files and dirs, but don't descend into CVS dir contents:
File::Finder->type('d')->name('CVS')->prune->comma->ls->in('.');
- follow
- Enables symlink following, and returns true.
- name(NAME)
- True if basename matches NAME, which can be given as a glob pattern or a
regular expression object:
my $pm_files = File::Finder->name('*.pm')->in('.');
my $pm_files_too = File::Finder->name(qr/pm$/)->in('.');
- perm(PERMISSION)
- Like find's "-perm". Leading
"-" means "all of these bits". Leading "+"
means "any of these bits". Value is de-octalized if a leading 0
is present, which is likely only if it's being passed as a string.
my $files = File::Finder->type('f');
# find files that are exactly mode 644
my $files_644 = $files->perm(0644);
# find files that are at least world executable:
my $files_world_exec = $files->perm("-1");
# find files that have some executable bit set:
my $files_exec = $files->perm("+0111");
- type(TYPE)
- Like find's "-type". All native
Perl types are supported. Note that "s"
is a socket, mapping to Perl's "-S", to
be consistent with find. Returns true or false, as
appropriate.
- print
- Prints the fullname to "STDOUT",
followed by a newline. Returns true.
- print0
- Prints the fullname to "STDOUT",
followed by a NUL. Returns true.
- fstype
- Not implemented yet.
- user(USERNAME|UID)
- True if the owner is USERNAME or UID.
- group(GROUPNAME|GID)
- True if the group is GROUPNAME or GID.
- nouser
- True if the entry doesn't belong to any known user.
- nogroup
- True if the entry doesn't belong to any known group.
- links( +/- N )
- Like find's "-links N". Leading
plus means "more than", minus means "less than".
- inum( +/- N )
- True if the inode number meets the qualification.
- size( +/- N [c/k])
- True if the file size meets the qualification. By default, N is in half-K
blocks. Append a trailing "k" to the number to indicate 1K
blocks, or "c" to indicate characters (bytes).
- atime( +/- N )
- True if access time (in days) meets the qualification.
- mtime( +/- N )
- True if modification time (in days) meets the qualification.
- ctime( +/- N )
- True if inode change time (in days) meets the qualification.
- exec(@COMMAND)
- Forks the child process via "system()".
Any appearance of "{}" in any argument
is replaced by the current filename. Returns true if the child exit status
is 0. The list is passed directly to
"system", so if it's a single arg, it
can contain "/bin/sh" syntax. Otherwise,
it's a pre-parsed command that must be found on the PATH.
Note that I couldn't figure out how to horse around with the
current directory very well, so I'm using $_
here instead of the more traditional
"File::Find::name". It still works,
because we're still chdir'ed down into the directory, but it looks weird
on a trace. Trigger "no_chdir" in
"find" if you want a traditional
find full path.
my $f = File::Finder->exec('ls', '-ldg', '{}');
find({ no_chdir => 1, wanted => $f }, @starting_dirs);
Yeah, it'd be trivial for me to add a no_chdir method.
Soon.
- ok(@COMMAND)
- Like "exec", but displays the command
line first, and waits for a response. If the response begins with
"y" or
"Y", runs the command. If the command
fails, or the response wasn't yes, returns false, otherwise true.
- prune
- Sets $File::Find::prune, and returns true.
- xdev
- Not yet implemented.
- newer
- Not yet implemented.
- eval(CODEREF)
- Ah yes, the master escape, with extra benefits. Give it a coderef, and it
evaluates that code at the proper time. The return value is noted for
true/false and used accordingly.
my $blaster = File::Finder->atime("+30")->eval(sub { unlink });
But wait, there's more. If the parameter is an object that
responds to "as_wanted", that method
is automatically called, hoping for a coderef return. This neat feature
allows subroutines to be created and nested:
my $old = File::Finder->atime("+30");
my $big = File::Finder->size("+100");
my $old_or_big = File::Finder->eval($old)->or->eval($big);
my $killer = File::Finder->eval(sub { unlink });
my $kill_old_or_big = File::Finder->eval($old_or_big)->ls->eval($killer);
$kill_old_or_big->in('/tmp');
Almost too cool for words.
- depth
- Like find's "-depth". Sets a flag
for "as_options", and returns true.
- ls
- Like find's "-ls". Performs a
"ls -dils" on the entry to
"STDOUT" (without forking), and returns
true.
- tar
- Not yet implemented.
- [n]cpio
- Not yet implemented.
- ffr($ffr_object)
- Incorporate a "File::Find::Rule" object
as a step. Note that this must be a rule object, and not a result, so
don't call or pass "in". For example,
using "File::Find::Rule::ImageSize" to
define a predicate for image files that are bigger than a megapixel in my
friends folder, I get:
require File::Finder;
require File::Find::Rule;
require File::Find::Rule::ImageSize;
my $ffr = File::Find::Rule->file->image_x('>1000')->image_y('>1000');
my @big_friends = File::Finder->ffr($ffr)
->in("/Users/merlyn/Pictures/Sorted/Friends");
- contains(pattern)
- True if the file contains "pattern"
(either a literal string treated as a regex, or a true regex object).
my $plugh_files = File::Finder->type('f')->contains(qr/plugh/);
Searching is performed on a line-by-line basis, respecting the
current value of $/.
A step consists of a compile-time and a run-time component.
During the creation of a
"File::Finder" object, step methods are
called as if they were methods against the slowly-growing
"File::Finder" instance, including any
additional parameters as in a normal method call. The step is expected to
return a coderef (possibly a closure) to be executed at run-time.
When a "File::Finder" object is
being evaluated as the "File::Find"
"wanted" routine, the collected coderefs
are evaluated in sequence, again as method calls against the
"File::Finder" object. No additional
parameters are passed. However, the normal
"wanted" values are available, such as
$_, $File::Find::name, and
so on. The "_" pseudo-handle has been set
properly, so you can safely use "-X"
filetests and "stat" against the
pseudo-handle. The routine is expected to return a true/false value, which
becomes the value of the step.
Although a "File::Finder" object
is passed both to the compile-time invocation and the resulting run-time
invocation, only the "options" self-hash
element is properly duplicated through the cloning process. Do not be
tempted to add additional self-hash elements without overriding
"File::Finder"'s
"_clone". Instead, pass values from the
compile-time phase to the run-time phase using closure variables, as shown
in the synopsis.
For simplicity, you can also just mix-in your methods to the
existing "File::Finder::Steps" class,
rather than subclassing both classes as shown above. However, this may
result in conflicting implementations of a given step name, so beware.
Randal L. Schwartz, <merlyn@stonehenge.com>
Copyright (C) 2003,2004 by Randal L. Schwartz, Stonehenge Consulting Services,
Inc.
This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself, either Perl version 5.8.2 or,
at your option, any later version of Perl 5 you may have available.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |