Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

switcher

by $CBAS (Scribe)
on Dec 31, 2000 at 01:18 UTC ( [id://49017]=sourcecode: print w/replies, xml ) Need Help??
Category: Utility Scripts
Author/Contact Info Sebastiaan 'CBAS' Deckers
mailto:cbas@screaming3d.com
Description: woohoo! my first code on PM! :-)
This little thing sweeps through directories to change the extensions of files (I use it to rename .MP3 files to .mp3 ... damn AltoMP3!)
#!/usr/bin/perl -w

# scribbled by CBAS [ mailto:cbas@screaming3d.com ]
# 30/12/2000
#
# "One more kick to get me started ..."
#   - Republica

use strict;

use subs qw {
    doDir
    doFile
    freakOut
};

use vars qw {
    $from
    $into
    $recur
    $renamed
    $directories
    $argument
};

freakOut and exit unless @ARGV >= 4;

$renamed        = 0;
$directories    = 0;
$from            = shift @ARGV;
$into            = shift @ARGV;
$recur            = shift @ARGV;

print <<EOL;
Renaming files from "foo$from" to "foo$into" ...
EOL

for $argument ( @ARGV ) {
    print "WARNING: \"$argument\" could not be found as a directory.\n
+"
        unless -d $argument and doDir ( $argument );
}

print <<EOL;
Renamed $renamed file(s) in $directories directories.
EOL

sub doDir {
    my ( $dir, $foo, @fools );
    $dir = shift;
    opendir DIR, $dir or return 0;
    @fools = readdir DIR;
    closedir DIR;
    shift @fools; shift @fools;
    foreach $foo ( @fools ) {
        if ( $recur and -d "$dir/$foo" ) {
            doDir ( "$dir/$foo" );
        } elsif ( -f "$dir/$foo" and $foo =~ /$from$/ ) {
            doFile ( "$dir/$foo" );
        }
    }
    $directories++;
    return 1;
}

sub doFile {
    my ( $file, $temp );
    $file = shift;
    $temp = $file;
    $file =~ s/(.*)$from$/$1$into/;
    if ( rename $temp, $file ) {
        $renamed++
    } else {
        print "couldn't rename $temp: $!"
    }
}

sub freakOut {
    print <<EOL;
Usage:
    $0 from into recur dir [dir [dir ... ]

Where:
    from
        the file extension you want to change
    into
        to what you want to change from
    recur
        renaming will happen recursively when set to anything but 0
    dir
        directory that will be traversed by the script

Example:
    $0 .MP3 .mp3 1 .
EOL
}
Replies are listed 'Best First'.
Re: switcher
by merlyn (Sage) on Dec 31, 2000 at 02:37 UTC
Re: switcher
by extremely (Priest) on Dec 31, 2000 at 16:32 UTC
    I really like freakOut and exit unless scalar @ARGV >= 4; I'm such a bonehead I thought you had typo'ed and left the pound off the front of a comment =)

    And the "scalar" part isn't needed. The >= comparator does that for ya.

    --
    $you = new YOU;
    honk() if $you->love(perl)

      ok, I took it out :-)
Re: switcher
by turnstep (Parson) on Dec 31, 2000 at 23:41 UTC
    Quick notes:
    • shift @ARGV is not needed: a simple shift will suffice.
    • Always check the result of your opendir and bail if it does not work.
    • Don't shift twice to disgard the "dot directories" from your readdir. Use a simple regex instead: it works very well with grep like so:
      @fools = grep { !/^\.\.?$/ } readdir(DIR);
    • Better yet, as mentioned above, use File::Find

      I know now that using File::Find would be better but I didn't know that when I wrote it so I used the right-tool-for-the-job ;-)

      I changed the code to check the result of the opendir, would it have caused problems otherwise?

      Why not shift it twice? Isn't that way faster than a grep?
      A shift would just ++ the array's base pointer (in C) so it sounds logical to me to use this over grep, right?

        Yes, two perlfunc:shifts or a perlfunc:splice would be faster than grep, if you can absolutely always rely on . and .. being the first two items listed in a directory. Which you probably can't even if that is the case on your system.

        A false return on opendir means that the system had a reason why it couldn't read what was in the directory (probably no read permission for user, you can find out in $!). This means that the call to readdir would fail (I think it would be fatal under warnings and strict) or if the program tried to keep on going @fools would be empty, causing other problems.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (2)
As of 2024-04-20 03:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found