Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

How do I recursively process files through directories

by paco (Pilgrim)
on Oct 27, 1999 at 01:16 UTC ( #847=perlquestion: print w/ replies, xml ) Need Help??
paco has asked for the wisdom of the Perl Monks concerning the following question:

I need to recurse through all the subdirectories of a given directory and rename all the files with a certain extension to a file with a different extension. Can anyone help?

Comment on How do I recursively process files through directories
RE: How do I recursively process files through directories
by vroom (Pope) on Nov 17, 1999 at 00:08 UTC
    You might want to check the File::Find module
      The Perl Cookbook from O'Reilly has an excellent recipe for this. I'd suggest picking it up for any person learning Perl. It's a handy guide for new programmers and seasoned programmers alike
        right on the Perl Cookbook is where it's at
Re: How do I recursively process files through directories
by Anonymous Monk on Nov 19, 1999 at 00:17 UTC
    There's some good info on File::Find in Perl in a Nutshell and the Perl Cookbook
Re: How do I recursively process files through directories
by nate (Monk) on Dec 23, 1999 at 03:44 UTC
    Here's a bit of example code that I often use:

    use File::Find;
    
    sub eachFile {
      my $filename = $_;
      my $fullpath = $File::Find::name;
      #remember that File::Find changes your CWD, 
      #so you can call open with just $_
    
      if (-e $filename) { print "$filename exists!\n"; }
    }
    
    find (\&eachFile, "mydir/");
    
I think *maybe*?
by Anonymous Monk on Dec 24, 1999 at 00:52 UTC
    Wouldn't this work? I haven't even run this to check for syntax, so DON'T EVEN trust me! I'm just as clueless as you are even more so probably, but I would like to know if this is generaly possible && if there are any downs of using this kind of approach.
    print &FilesExt('/tmp','csv','txt')." files renamed\n";
    
    sub FilesExt {
    
        my ($startpath,$orgext,$newext) = @_;
        my ($count);
    
        foreach $leaf (glob("$startpath/*")) {
            if (-d $leaf) { 
                $count += FilesExt($leaf,$orgext,$newext);
            } elsif ($leaf =~ m/$orgext\z/i) { #case insensitive maybe?
                my $oldleaf = $leaf;
                $leaf =~ s/$1/$newext/;
                rename($oldleaf,$leaf) or warn();
                ++$count;
            }
        }
        return($count);
    }
    
    Comments, monks?
      YAY! I just ran it... it does work, but I'd still like to know if this is potentially a bad way of doing things... Cheers.
RE: How do I recursively process files through directories
by thowland (Novice) on Dec 27, 1999 at 03:46 UTC
    If in a *nix environment, and not wanting to goof with the File::Find module (which are certainly the _right_ way to do this), the fastest way to _type_ the solution may be:
     foreach $file (split (/\n/,  `find .`)) {
        $newFile = $file;
        $newFile =~ s/foo/bar/;
        rename ($file,$newFile) 
        }
    
(Ovid - poor paco) Re: How do I recursively process files through directories
by Ovid (Cardinal) on Jun 23, 2001 at 03:32 UTC

    Poor paco. I wonder what happened to /h(im|er)/? I suppose we'll never know. Did paco turn to VBScript? Did paco become a Java programmer? Is paco selling hot dogs on a street corner somewhere?

    I suppose that paco asked a reasonable enough question, though by today's standards, perhaps /s?he/ would be flamed for not even trying to post code. I'm going to give paco a ++ for this node, since this is one of the first, if not the first question to be asked here.

    Wouldn't it be interesting if, at some point in the distant future, paco gave up selling hot dogs, returned to Perl, and found /h(im|er)/self a Saint because everyone came by and gave paco's lonely little node a ++?

    :-)

    Cheers,
    Ovid

    Update: Don't waste your votes on this node. Vote for paco!

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

      LMAO@OVID! I'm in tears laughing~ FUNNY~ :)

      Thanks to Paco I achieved my new rank of Sexton. Thank you Paco! I'll vote for you again If we meet...in another dimension, perhaps ;-).

      Where is Paco? Perhaps we shall worship a new Saint (Saint Recursive).

Re: How do I recursively process files through directories
by antipaco on Sep 08, 2001 at 04:31 UTC
    No. No-one can help you, Paco. You are beyond help.

    The ghost has spoken
      Is antipaco a troll possibly? Hmm. Paco is long gone, about 97 weeks now, and going strong.

      Maybe we should let people ++ Paco if they want to.

      Andy Summers
        I am no troll. I am the Ghost in the Machine.
Re: How do I recursively process files through directories
by antipaco on Sep 08, 2001 at 19:36 UTC


    ATTENTION ALL MONKS:

    Don't vote for the monkey when you can vote for the organ grinder.

    paco--!

    CmdrTaco++!

    The Ghost has spoken.
      You are obviously not the real antipaco. The real antipaco would only have posted once.

      Why would the real antipaco need three times as many nodes as the one true paco?

      elbieelbieelbie

        Come now, if the antipaco is better than the real paco then he should not even need to post at all!! ;-)

        Elda Taluta; Sarks Sark; Ark Arks

Re: How do I recursively process files through directories
by Discipulus (Curate) on Sep 12, 2002 at 12:40 UTC
    on my first script (i'm still a newbie) I had the same problem. I have solutioned it in this way:
    
    use DirHandle;
    use Cwd;
    use File::stat;
    
    $strarting_dir=cwd;
    
    &creaalbero($strarting_dir);
    &alkilo($dimensione);
    
    print $dimensione;
    
    sub creaalbero
    {
      chdir $_;
    	$cwd=cwd;
      $percorso="$cwd"."\\";
      $dh = new DirHandle;
    	$dh->open("$_");
      @lista = ($dh->read());
    	shift @lista;
    	shift @lista;
      foreach $dir(<*>)
    	{
     		if (-d $dir)
    		{
                            chdir $dir;
    			&creaalbero();
    			$albero{"$percorso"}=directory;
    			chdir"..";
    		}
    
    		if (-f $dir)
    		{
                        $current=cwd;
                        $albero{"$current"."\\"."$dir"}=file;
    	            $stat=stat ($dir);
    		    $dimensione+=($stat->size);
                    }
    
    	}
    
    }
     sub alkilo
    {
     $dimensione=$dimensione/1024;
     @grand= qw/Tb Gb Mb Kb /;
     if ($dimensione>=1024) { pop @grand ; &alkilo($dimensione)}
     unless($dimensione==0){$molt=pop @grand}
     $dimensione =~ /^\d*\.\d?\d?/;
     $dimensione="$&"." "."$molt";
    }
    
    
    This code make %albero with the paths as keys and directory or file as values(is unnecessary to recurse the directory).
    It calculate the size of the sub tree and print out the value.
    The magic point is:
    foreach $dir(<*>)

    NOTE: creaalbero means maketree and percorso means path.

    seeU L*
Re: How do I recursively process files through directories
by webfiend (Vicar) on Feb 24, 2003 at 19:00 UTC

    I gave paco my ++ long ago, but a recent glance at the Esperanto language showed something which grabbed my attention. According to the Esperanto dictionary, paco means peace.

    pac/o peace, ~a ~ful, ~ama ~loving, mal~(ig^)i (get in a) quarrel

    So all this time, we've been voting ++ to peace. Seems appropriate to the monastery, yes? ;-)


    I just realized that I was using the same sig for nearly three years.

      *GASP* Then what's antipaco?
        If you need to ask, you are not ready to know.
Re: How do I recursively process files through directories
by Mork29 (Scribe) on Aug 07, 2003 at 12:10 UTC
    Did anybody else notice that the great paco has returned! or he had at least. He was listed as logging in as recently as July 11, 2002! Did paco loose that hot dog vendor job and decide to give Perl another shot? Did he see his new found reputation and get scared back away? This mystery shall never end...
      I see that Mork29, Paco sure is an elusive fella!

      OK, an additional question from another perl n00b. My search basically turned up this thread. So...

      Anyhow, how do you get what File::Find *finds* into a list (array) for further processing?

      The following code snippet only prints the list of files to STDOUT, but doesn't dump them into @stuff. What am I doing wrong?


      Code:
      #!/usr/bin/perl use strict; use warnings; use File::Find; use MP3::Mplib; + print "Enter the full path of your MP3 directory:\n"; my $mp3_dir = <STDIN>; chomp($mp3_dir); + my @stuff = find(\&wanted, $mp3_dir); + foreach my $item ( @stuff ) { my $mp3 = MP3::Mplib->new($item); my $v1tag = $mp3->get_v1tag; my $v2tag = $mp3->get_v2tag; + while (my ($key, $val) = each %$v1tag) { print "$key\: $val\n"; } while (my ($key, $val) = each %$v2tag) { print "$key\: $val\n"; } } + sub wanted { print "$File::Find::name\n" if -f && ! -d && m/\.mp3$/i; }
        You have to put them where you want them. In your example that would be
        my @stuff; sub wanted { push @stuff, $File::Find::name if -f && ! -d && m/\.mp3$/i; } find(\&wanted, $mp3_dir);
        or better
        my @stuff; find(sub { push @stuff, $File::Find::name if -f && ! -d && m/\.mp3$/i; }, $mp3_dir);
        Except it isn't better, since all you're doing is to process them one by one. So do it right in the callback function:
        find(\&wanted, $mp3_dir); + sub wanted { return unless -f && ! -d && m/\.mp3$/i; print "$File::Find::name\n" my $mp3 = MP3::Mplib->new($item); my $v1tag = $mp3->get_v1tag; my $v2tag = $mp3->get_v2tag; + while (my ($key, $val) = each %$v1tag) { print "$key\: $val\n"; } while (my ($key, $val) = each %$v2tag) { print "$key\: $val\n"; } } +
        Update: That should be push @stuff, $File::Find::name, not push @stuff, $_, otherwise you loose the path.

        Makeshifts last the longest.

Re: How do I recursively process files through directories
by Qiang (Friar) on Feb 22, 2004 at 05:45 UTC
    It's amazing that people keep coming back and checking on paco.

    i think paco will be coming back again 2004 Jun 11.

    Muwuhahahah.... //

      PACO FOR PRES IN '04!!!! He's running on the hotdog party ticket.

      Grygonos

      UPDATE: As you can see from my timestamp, it's now 2004 Jul 13. Unfortunately, paco is a no-show. When you say your prayers tonight, think of paco. Hopefully, he hasn't turned away from perl. For all we know, paco could emerge as the next Damian someday. He might not ever know of his status here at PM. paco could even be sitting nearby... you know, the guy picking his nose, yeah, that's the one.

      Here's to another 5-ish years of paco and Perl Monks

      mhoward - at - hattmoward.org
Re: How do I recursively process files through directories
by danderson (Beadle) on Jun 17, 2004 at 23:57 UTC
    Found this somewhere else, and it works wonderfully for me, so I thought I'd pass it on (yes, it's recursive, but it's also easier to read/write/maintain than the iterative sol'n above):

    sub recurse { my($path) = @_; print( "working in: $path\n" ); # append a trailing / if it's not there $path .= '/' if($path !~ /\/$/); # loop through the files contained in the directory for my $eachFile (glob($path . '*')) { # if the file is a directory if( -d $eachFile) { # pass the directory to the routine ( recursion ) recurse($eachFile); } else { handleFile( $eachFile ); } } }

    Go paco!
      Its way past June 11 2004, where is paco? I really miss h[im|er]. We could have been such famous friends.
JAPH?
by apotheon (Deacon) on Dec 18, 2004 at 16:46 UTC

    print "Just another Paco hacker,";

    print substr("Just another Perl hacker", 0, -2);
    - apotheon
    CopyWrite Chad Perrin

Re: How do I recursively process files through directories
by hok_si_la (Curate) on Feb 23, 2005 at 17:51 UTC
    For those of you most interested in the fate of our dear Paco, I suggest watching Arnold Schwarzenegger's "The Running Man". Paco's adventures finally caught up to him.
A Tale of a Wisdom Seeker
by gnustavo (Novice) on Jun 04, 2005 at 04:22 UTC
    It was a long journey for me. For several years I struggled with dollars, at-signs, and percents in order to uncover the sheer beauty that lies within the gems that are some of the most elegant CPAN modules.

    I wandered alone through this path until I was able to see the beauty where it is. But I wanted more. I wanted to be able to create this kind of beauty by myself. I just didn't know how.

    Until today, when I stumbled at the doors of this Monastery. As I entered here I realized that this should be the place where the light would be shown to me. I was amazed by the wisdom I could see here. I was delighted by the beatiful gems of Perl code I found. I was paralized by the sheer grandeur of the resources available.

    Until I was shocked to see that Paco was here before. Paco, that good old friend of mine that one day said to me that he had a problem to solve and that he would look for an answer somewhere. And so he went. Never to be seen again.

    Paco, where are you?

Re: How do I recursively process files through directories
by sk (Curate) on Jul 24, 2005 at 05:56 UTC
    print ("Perennially Anonymous Comfortably Obfuscated,");
Re: How do I recursively process files through directories
by Milamber (Beadle) on Aug 28, 2006 at 13:31 UTC
    This should be listed as recommended reading for all newcomers, as it goes some way to revealing the subtleties of wit and community that make sites like this one rare. Anyhoo...almost 3/4 of the way through 2006, still no Paco. Like blurred photo's of BigFoot and Nessie, that single post may prove enough to fuel a rumour, but be insufficient evidence to say that Paco was even real.

    If the world is my oyster...then where the hell is my pearl?

      Maybe he just forgot his password?

      sas
[untitled node, ID 603987]
by avi_learns_perl (Novice) on Mar 09, 2007 at 14:07 UTC
    Re: How do I recursively process files through directories
    by cmv (Chaplain) on Nov 30, 2007 at 13:33 UTC
      My son discovered this last night. Perhaps a clue on his current whereabouts?
    Re: How do I recursively process files through directories
    by telemachus (Friar) on Jul 12, 2008 at 01:00 UTC
      A perfect example of why I like this site and the whole internet. You have to love the way strange little nooks like this just pop up and then *don't* go away. I stop by on a quiet (for me) Friday night, and I check in on What's New at PerlMonks. The top entry refers to this paco guy, so I click on his name. As I said, a quiet evening.

      So of course it sticks out right away that (1) this guy has one write up, (2) he hasn't been around since 1999 and (3) he's got 717 XP and is a Pilgrim. That makes me curious enough to end up here.

      After re-checking his home node, I also notice that (4) Paco joined the site at 21:12 (my time) and was last seen at 21:16 on the same day. Four minutes for him, going on 9 years for his after-life on the site. Not bad, not bad at all.

      Of course, questions remain. Where is paco? Why did he leave so soon. Why does Mork29 say above that he came back in 2002? Or, the other way around, why does paco's home node not jibe with this? Who put the picture up on paco's home node?

      Lots of questions, but no answers. In any case, good night paco - wherever you are.

    Re: How do I recursively process files through directories
    by Anonymous Monk on Feb 26, 2009 at 19:19 UTC
      Even better I have done a search for a VBScript that would do a recursive file search, and this site is on the list.....Could Paco have gone to their home country, get elected President only to be removed from power by bloodthirsty drug cartel memebers? we will never know. Here's to 9 years and almost 5 months. Anyone want to plan a party around the ten year mark?
    Re: How do I recursively process files through directories
    by xbmy (Friar) on Dec 04, 2009 at 19:09 UTC

      Ten years passed, we still are very interested in this problem, I got some code to get the total number of files under a directory, sub directory is also included.

      #!/usr/bin/perl use strict; use warnings; my $location = "the path of directory you want to process"; #root dir +ectory my $n = 0; readsub($location); print "Found $n file(s)!\n"; #print the total number of files you fo +und exit; sub readsub { my ($file_t) = @_; if (-f $file_t) { #if its a file $n++; #the total number of files } if (-d $file_t) { #if its a directory opendir(AA,$file_t) || return; my @list = readdir(AA); closedir (AA); my $file_to_act; foreach $file_to_act (sort @list) { if ($file_to_act =~ /^\.|\.$/) { next; } else { readsub("$file_t/$file_to_act"); } } } }
      Enjoy!
    Re: How do I recursively process files through directories
    by xbmy (Friar) on Dec 04, 2009 at 19:35 UTC
      Another way to recurse a directory and print the files you want to get,the following is the code.
      use strict; use warnings; sub ransack { #dir,\@files my $dir=shift; my $files=shift; my @array=glob("$dir\\*"); foreach my $item (@array) { if(-d $item) { ransack($item,$files); } else { $files->[@$files]=$item; } } } my ($array, @array); ransack("path of your directory",\@array); #path of your directory foreach $array (@array) { if ($array=~/txt|csv/) { #match your file format print ("$array\n"); } }
      Enjoy!
    Re: How do I recursively process files through directories
    by jonix (Friar) on Jun 20, 2011 at 13:56 UTC
      O paco, Where Art Thou?
    Re: How do I recursively process files through directories
    by koolgirl (Hermit) on Jul 27, 2011 at 20:17 UTC

      Oh, long lost love of my life, paco, why have you left me broken-hearted for so long....I miss you, the children miss you...come home paco........

        I'm with Ruby now, shes sooo shiny

          paco would never be fooled by the facade of shininess you mention...

        this is so funny, it's his only post and 12 years passed ...
    Re: How do I recursively process files through directories
    by Anonymous Monk on Jun 27, 2012 at 04:48 UTC

      The Mayan calander tells us that Saint paco will return on 12/12/12!

    Re: How do I recursively process files through directories
    by Discipulus (Curate) on Oct 08, 2013 at 11:44 UTC
      12/12/12 is passed..

      may be we'll be more lucky in 13/13/13 ?
      Paco come back!
      L*

      there are no rules, there are no thumbs..

    Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Node Status?
    node history
    Node Type: perlquestion [id://847]
    help
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others pondering the Monastery: (7)
    As of 2014-10-25 18:22 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      For retirement, I am banking on:










      Results (147 votes), past polls