i've had considerable trouble with playing other people's mp3s (notably, those written with spaces and single quotes (').. so i wrote a small script that will rename an entire directory (but not subdirectories, yet (: ) full of mp3s, to where they're easier on the command-line completion. eg. "some file's desperate attempt at proper grammar.mp3" becomes "some_files_desperate_attempt_at_proper_grammar.mp3"
this is for all you slow/lazy typers out there. (:

PS: if someone can add recursiveness to this script, i'd be very thankful (i haven't had the time); also, i made it to where it wouldn't rename 'hidden' (leading dot) files, as a feature. (due to certain programs saving incomplete files with leading dots)
Update: Fixed broken code (for for ignoring hidden files) Update 2: posting it to code catacombs, it grew too big with recursiveness to really be considered a snippet. (hehe, and this started with a one-liner.)
#!/usr/bin/perl -w use strict; # or die $! (8 use Getopt::Std; use vars qw/$opt_h/; getopts('hr'); $0=~s|.*[/\\]||; my($arg) = $ARGV[0] if ($ARGV[0]); &usage if ((!$ARGV[0]) || ($opt_h)); &usage if($opt_h); &simple_rename($arg); sub usage { die "usage\e[1m:\e[m $0 \e[1;30m/\e[mpath\e[1;30m/\e[mto\e[1;30m/\e[mm +p3\e[1;30m/\e[mdirectory \n\n"," " x 7, "Get rid of annoying characte +rs out of files (spaces and single quotes)\n", " " x 7,"you \e[31mmus +t\e[m have read\e[1;30m/\e[mwrite permission to directory!\n", " " x +7, "eg. $0 \e[1;34m~\e[m\e[1;30m/\e[mmp3s\e[1;30m/\e[m\n"; } sub simple_rename { my($cwd) = $_[0]; opendir(DIR, "$cwd") or die "can't open $cwd: $! !\n"; my @mp3s = grep { /^[^\.].*\.mp3$/ && -f "$cwd/$_" } readdir(DIR);clos +edir(DIR); opendir(DIR, "$cwd") or die "can't open $cwd: $! !\n"; my @skipped = grep { /^[\.].*\.mp3$/ && -f "$cwd/$_" } readdir(DIR);cl +osedir(DIR); chdir "$cwd" or die "couldn't cd to $cwd: $!\n"; foreach (@mp3s) { if ((/ /) or (/'/)){ my $old = $_; s/ /_/g; s/'//g; rename $old,$_; print "$old \e[31m->\e[m $_ \n"; } } foreach (@skipped){ print "skipped [\e[1;34m$_\e[m] due to leading dot. (\".\")\n" +; } }

Replies are listed 'Best First'.
Re: more renaming! (mp3s) (now with File::Find!)
by grinder (Bishop) on Jul 18, 2001 at 00:55 UTC

    Making a recursive directory scan is easy, you just have to use File::Find, which is part of Perl's standard distribution.

    A few points about my code: I use tr// instead of s/// as its more efficient when working on single character substitutions (or transliterations, to be precise). Also you should check if the target file already exists before attempting the rename... and always check system calls for errors.

    #! /usr/bin/perl -w use strict; use File::Find; my $root = shift || '.'; find( sub { return unless /\.mp3$/ and /[ ']/; (my $new = $_) =~ tr/ '/__/; if( -e $new ) { warn "Can't rename $_ to $new (latter already exists).\n"; } else { rename $_, $new or warn "Could not rename $_ to $new: $!\n"; } }, $root );
    --
    g r i n d e r
Re: more renaming! (mp3s)
by spm (Acolyte) on Jul 18, 2001 at 14:13 UTC
    You can always find all the files with globbing, like so:
    foreach(<*.mp3>) { }
    ... might shorten up your code a bit. You could also, stat() each file and check its type, if it's a directory, decend into it and call the function again...
      true, but i thought globbing required csh? some platforms (heck, i've seen some unices even) fail on that. readdir + grep seems to work universally... or at least, until they make a worse universe. (:

        but i thought globbing required csh?
        This is no longer true. Starting from perl 5.6.x the glob is performed internally.

        -- Hofmator