litarena has asked for the wisdom of the Perl Monks concerning the following question:


In shell it's common to do a find plus exec, or loop like
this:

for i in `find . -name "*.*"`; do
command one;
command two;
done


But what I've seen people doing in perl is this

find . -name *.bak | perl -ne 'print if 1..3'

Question is, can you actually do the find loop from within
perl (or do you have to use the find CPAN module)
making it a little bit unwieldy for a oneliners, or
mini-script, perl solution.


Replies are listed 'Best First'.
Re: find loops in perl
by moritz (Cardinal) on Feb 16, 2012 at 10:55 UTC
Re: find loops in perl
by afoken (Chancellor) on Feb 16, 2012 at 19:15 UTC

    find2perl [find arguments] creates a skeleton perl script to replace find and shell scripting:

    user@host>find2perl -type f -name '*.foo' -exec echo '{}' #! /usr/bin/perl -w eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' if 0; #$running_under_some_shell use strict; use File::Find (); # Set the variable $File::Find::dont_use_nlink if you're using AFS, # since AFS cheats. # for the convenience of &wanted calls, including -eval statements: use vars qw/*name *dir *prune/; *name = *File::Find::name; *dir = *File::Find::dir; *prune = *File::Find::prune; sub wanted; sub doexec ($@); use Cwd (); my $cwd = Cwd::cwd(); # Traverse desired filesystems File::Find::find({wanted => \&wanted}, '.'); exit; sub wanted { my ($dev,$ino,$mode,$nlink,$uid,$gid); (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && -f _ && /^.*\.foo\z/s && doexec(0, 'echo','{}'); } sub doexec ($@) { my $ok = shift; my @command = @_; # copy so we don't try to s/// aliases to consta +nts for my $word (@command) { $word =~ s#{}#$name#g } if ($ok) { my $old = select(STDOUT); $| = 1; print "@command"; select($old); return 0 unless <STDIN> =~ /^y/; } chdir $cwd; #sigh system @command; chdir $File::Find::dir; return !$?; }

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)