PDA

View Full Version : Quick prob.


recluse
07-23-2002, 02:13 AM
The script does as I want right up until the rename part, at that point it undoes the changes that I made I'm left with the old name of the mp3. Oh and btw, somebody told me that this code was uglier than there's. I haven't read the style portion of Programming Perl yet, but if someone would like to show me 'the right way' that would be much appreciated!

# 2002 07 18
# Scans a dir and makes the naming convention
# a little more consistent
#

# Take ARGS for dir
if (defined($ARGV[0])){
opendir(MP3DIR, $ARGV[0]) or die "Can't open $ARGV[0]\n";
}

foreach(readdir(MP3DIR)){
$new = $_;
$new =~ tr/A-Z/a-z/;
$new =~ s/(\w) (\-)/$1$2/g;
$new =~ s/(\-)(\_)/$1/g;
$new =~ s/ /\_/g;
rename $_, $new;

}

Strike
07-23-2002, 09:01 AM
So, this seems to do the following to each file:
1) Lower case on all letters in the filename
2) Remove all spaces between letters/numbers and dashes (but leaving them after, I should point out, so a name like "foo - bar" would become "foo- bar" after that change)
3) Removes all underscores that immediately follow dashes in the name.
4) Changes all spaces to underscores.

Shouldn't 4 and 3 be swapped? That way something like "foo - bar.mp3" would become "foo_bar.mp3" instead of "foo-_bar.mp3". (At first glance, that seems to be what would happen anyway)

recluse
07-24-2002, 03:50 PM
No, the regexes seem to work fine. since the - in the file name usually will seperate the band and song, so I perfer foo-bar.mp3 instead of foo_bar.mp3. The only problem I still run into is having the changes take affect. If I put print statements after each change I can see that it's going fine until the 'rename' part where the name reverts back to the original form instead of the changed version.

Bradmont
07-24-2002, 04:46 PM
Instead of writing your own script to rename stuff, I'd suggest using the "rename" script that's included with perl (at least, with the debian package). It's really quite handy, use like this:

rename tr/[A-Z]/[a-z] *.mp3
rename s/mp3/ogg/ *.mp3

or whatever, any perl regex works :)

TheLinuxDuck
08-07-2002, 12:47 PM
The problem lies with the fact that the directory where the mp3's lie may not be the currect directory. And since the code is not giving rename a full path (or changing into the dir), rename can't find the file. not to mention, a direct readdir will also include . and .. as part of it's list, and any other directories in the given directory. Although rename won't change them, it's still a good idea to remove then from the list. Also, error checking is always a good thing. Rename would have told you that it couldn't find the files if the code said something like:

rename $old, $new or print "Error renaming: $!\n";

I'd prolly say something more like:

# this code has not been tested
for my $singleDir(@ARGV) {
-d $singleDir or (print "Not a directory: $singleDir\n" and next);
chdir $singleDir or (print "Couldn't chdir into $singleDir: $!\n" and next);
foreach my $file(grep !/^\.\.?/, readdir DIR) {
-d $file and (print "Dir found: $file: Skipping...\n" and next);
# regexp stuff
rename $file, $new or print "Rename failed: $!\n";
}
closedir DIR;
}

There are some other things that could be done with it, but you get the general idea. (=

Also, this doesn't do anything for recursive directory's, though. It wouldn't be too hard to modify it and put the main loop into a function, and call it when a dir is found.. or use File::Find, which would make it quite easy to recurse.

l2kashe
08-21-2002, 03:52 PM
or even

$mp3 = $ARGV[0];

# test for absolute path, or hardcode one in here

foreach $file (readdir(MP3)) {
#
# Skip if it starts with a . or isnt a regular file
next if ($file =~ /^\./ || ! -f "$base/$file");

$tmp = lc($file);
$tmp =~ s/\s+/ /g;
$tmp =~ s/ - /_/g;

rename ("$base/$file", "$base/$tmp");
}

l2kashe
08-21-2002, 03:53 PM
ARG why is the indentation off on these boards???!!!

Strike
08-22-2002, 06:57 AM
Originally posted by l2kashe
ARG why is the indentation off on these boards???!!!

Use code tags (enclose with [ code ] and [ /code ] without the trailing and leading spaces between the []s).


if (tag.used && (tag.type == "code")) {
indentation.correctness = true;
}