#!/usr/bin/perl
use warnings;
use strict;

push @INC, "C:/Perl/Modules";

print "What is current download directory? ";
my $dir = <STDIN>;
opendir DH, $dir or die "Can't open directory...";
my $parent = $_;
while ($parent = readdir(DH))
{
	next if $parent eq "." or $parent eq "..";
	if(-d $parent)
	{
		opendir DI, "$dir/$parent" or die "Can't open directory...";
		while ($_ = readdir(DI))
		{
			next if $_ eq "." or $_ eq "..";
			if (/(\w+ )(\d+)\b(\d+)\b(.*)(\d+)/)
			{
				print "Long File";
				our $month = $1;
				our $day = $2;
				our $year = $3;
				our $name = $5;
			}
			else if(/(\w+ )(\d+)\b(\d+)\b(.*)(\d)\b/)
			{
				print "Short File";
				our $month = $1;
				our $day = $2;
				our $year = $3;
				our $name = $5;
			}
		}
	}
}
print "Done";

I use Windows Vista with ActivePerl.
Basically I have a bunch of folders within a large parent folder each with two mp3 files and a txt file (which I don't care about) in this format:
Month DD YYYY . Name . ##(#)kbps . XX(X) minutes.mp3
the two mp3 files are exactly the same format that the ones with two digit minutes I want to name one way (lets say "short") and ones with 3 digits I want to name another way (lets say "long"). I also have other mp3 files which are not in this format and I cannot figure out a way to grab the length or bitrate of an mp3 file in perl (maybe someone can help with this too).

Anyway, this code does not run. I get a syntax errors at lines 28 and 38. I am using 'else if' wrong probably...
(ignore my misplaced mys and ours)

I am very new to Perl programming and would love some help. Thanks.

Recommended Answers

All 9 Replies

try this:

my $dir = <STDIN>;
chomp $dir;#<-- remove the end of line character(s)

and change "else if" to "elsif".

It's still giving me a syntax error at the else if line and the final closing bracket of the while loop.
(I'm sure you solved one problem with it though)

Try this, I didn't really fix any syntax errors though besides "else if":

#!/usr/bin/perl
use warnings;
use strict;

push @INC, "C:/Perl/Modules";

print "What is current download directory? ";
my $dir = <STDIN>;
chomp $dir;
opendir DH, $dir or die "Can't open directory: $!";
while (my $parent = readdir(DH))
{
	next if ($parent eq "." or $parent eq "..");
	if(-d $parent)
	{
		opendir DI, "$dir/$parent" or die "Can't open directory: $!";
		while ($_ = readdir(DI))
		{
			next if ($_ eq "." or $_ eq "..");
			if (/(\w+ )(\d+)\b(\d+)\b(.*)(\d+)/)
			{
				print "Long File";
				our $month = $1;
				our $day = $2;
				our $year = $3;
				our $name = $5;
			}
			elsif(/(\w+ )(\d+)\b(\d+)\b(.*)(\d)\b/)
			{
				print "Short File";
				our $month = $1;
				our $day = $2;
				our $year = $3;
				our $name = $5;
			}
		}
	}
}
print "Done";

Oops, I missed the elsif change you mentioned...
It runs now, but I didn't get any Long File or Short File returns, just the Done.
So either my regexps are wrong, or my directory handling is wrong. Am I doing anything else wrong?

The regular expression:
(\w+ ) - the month (any amount of word characters and a space)
(\d+) - 1 or 2 numbers (the day)
\b - a boundary
(\d+) - 4 numbers (the year)
\b - a boundary
(.*) - everything up to the last numbers in the string (because its greedy
(\d+) - 2 or 3 numbers (the length)

Is this wrong?

Work on the script one problem at a time. First check that the directory I/O is working:

use warnings;
use strict;

push @INC, "C:/Perl/Modules";

print "What is current download directory? ";
my $dir = <STDIN>;
chomp $dir;
print "Current Directory is: $dir\n\n";
opendir DH, $dir or die "Can't open directory: $!";
while (my $parent = readdir(DH)){
   next if ($parent eq "." or $parent eq "..");
   print "> $parent\n";
   if(-d $parent){
      opendir DI, "$dir/$parent" or die "Can't open directory: $!";
      while (my $sub = readdir(DI)){
         next if ($sub eq "." or $sub eq "..");
         print ">>> $sub\n";
      }
      close DI;
   }
}
close DH;

Then if that is working try adding in the regexp stuff and see what happens. If it does not work then you have to figure out what the problem is.

It lists all of the files and subdirectories from parent directory but nothing in any of the subdirectories...

If you want to drill down through all sub directories you should use the File::Find module that comes with perl.

If you really want to do it manually you need a recursive function, something like this:

use warnings;
use strict;

#push @INC, "C:/Perl/Modules";

print "What is current download directory? ";
my $dir = <STDIN>;
chomp $dir;

list($dir);

sub list {
   my ($dir) = @_;
   print "$dir\n";
   opendir(my $DH, $dir) or do{print "Can't open $dir: $!\n"; return};
   my @list = grep {$_ ne '.' and $_ ne '..'} readdir $DH;
   foreach my $file (@list){
      print "\t$file\n";
      list("$dir/$file") if (-d "$dir/$file");
   }
}
commented: Helped a lot! +2

Thanks a lot!!
Now I need to experiment with regular expressions...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.