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

Hmm... just starting to use PERL and running into all kinds of problems =). Anyways, I have over 3500 mp3s and they are nammed differently, for example, blah_blah_-_blah_blah, or Blah_blah - Blah blah. I am trying to write a script to parse through all the mp3s and rename them like Blah Blah - Blah Blah.mp3. Capital letter and spaces not underscores. First problem with this is how to get all the file names into a variable that I can parse. Secondly, do I need to do any arrays or splitting? Thanks for the input and information ;) Chris

Replies are listed 'Best First'.
Re: File Name Standardization
by Zaxo (Archbishop) on Jun 22, 2002 at 01:41 UTC

    There are a number of perl functions to help. tr/_/ / will transliterate underscore to space. s/(\w+)/ucfirst $1/eg will give initial caps. opendir/readdir, glob, or <pathglob> will produce a list of files to work on. Finally, rename will do the job.

    # Assumes no non-mp3 regular files in the dir use File::Basename; for (glob('/path/to/*')) { -f or next; # don't mess with directories, etc my ($file,$dir,$ext) = fileparse($_,qr/\.[^.]+$/); $file =~ tr/_/ /; $file =~ s/(\w+)/ucfirst $1/eg; rename $_, $dir.$file.'.mp3' or warn 'Failed to rename ',$_,': ',$ +!; }
    Untested, but it's pretty straightforward. I do underscore transliteration first, because underscore is a \w character and would interfere with uppercasing the way I do it. File::Basename is in the standard distribution. The regex in fileparse() is used to select what counts as a filename extension. I made it everything from the last dot to the end. Alter to taste.

    Update: Added warning for failed rename. Fixed pasteo.

    After Compline,
    Zaxo

Re: File Name Standardization
by mikeirw (Pilgrim) on Jun 22, 2002 at 01:12 UTC
    Check out this node for something very similar to what you're trying to do.
Re: File Name Standardization
by kvale (Monsignor) on Jun 22, 2002 at 01:22 UTC
    Let's start out by reading files from $some_dir:
    opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!"; @files = grep {-f "$some_dir/$_" } readdir(DIR); closedir DIR;
    Then for each file, parse and change the name:
    foreach (@files) { /^(\w+)\W+(\w+)\W+(\w+)\W+(\w+)$/; next unless $1 && $2 && $3 && $4; rename "$some_dir/$_", "$some_dir/$1 $2 - $3 $4.mp3" or die "Could not rename file: $!"; }

    -Mark
Re: File Name Standardization
by valdez (Monsignor) on Jun 22, 2002 at 11:24 UTC

    You may want to consider using module MP3::Info, which can manipulate mp3 tags. So, after having cleaned up your collection, you could also set correct tags.

    Have fun, Valerio

Re: File Name Standardization
by stefp (Vicar) on Jun 22, 2002 at 22:13 UTC
    Note that if convert your file to include, you are bound to have problems when using them with Unix except if you know about find -print0 and xargs -0. And many shell scripts don't grok filesname with space. This less a problem with perl. But if you don't know that you are tighly bound to the dark side of the force.

    -- stefp -- check out TeXmacs wiki

Re: File Name Standardization
by Anonymous Monk on Jun 22, 2002 at 23:53 UTC
    Wow thanks so much for all your help =D I'll get started right away =) Cheers, Chris