Re: how to create folders
by davorg (Chancellor) on Mar 28, 2007 at 08:08 UTC
|
set max_dir to 0
foreach directory found
parse number out of directory name
if number is larger than max_dir
set max_dir to number
end if
end for
increment max_dir
for 1 to 10
create directory using value of max_dir
increment max_dir
end for
Which part did you have a problem with?
| [reply] [d/l] |
Re: how to create folders
by GrandFather (Saint) on Mar 28, 2007 at 08:20 UTC
|
use readdir to read the existing directories into an array. Use grep to filter out any files and bogus directories that snuck in while you weren't looking. sort the resulting array and pull off the last element using [-1]. Parse out the number using a regex. (Actually the code is shorter than the description, but you get that with Perl.)
DWIM is Perl's answer to Gödel
| [reply] |
Re: how to create folders
by grinder (Bishop) on Mar 28, 2007 at 08:46 UTC
|
I would use glob to find the files that exist in the directory, and extract the numeric component (or 0 if there's none). Then sort those numbers in descending order, and take the first one. That gives us our highest directory.
It is then a simple matter of programming to use File::Path and create the ten new directories, adding steps of a thousand to the highest number, and prepending the stem of the directory.
In fact, minus a certain amount of fluff, it only takes two statements: one to find the highest, and one to create the directories:
use strict;
use warnings;
use File::Path 'mkpath';
my $stem = 'object';
my $highest = (
sort {$b <=> $a}
map { /(\d+)$/ ? $1 : 0 }
glob("$stem*")
)[0];
mkpath( [map {$stem . ($highest + $_*1000) } 1..10],
1, # verbose
0777 # full access for everyone
);
• another intruder with the mooring in the heart of the Perl
| [reply] [d/l] |
Re: how to create folders
by Anno (Deacon) on Mar 28, 2007 at 08:37 UTC
|
Is this program the only one that creates this type of folder? If so, the solutions suggested by davorg, TOD and GrandFather are fine. If other programs can concurrently create directories, you may need a lock mechanism to avoid race conditions.
Anno | [reply] |
Re: how to create folders
by Peamasii (Sexton) on Mar 28, 2007 at 09:03 UTC
|
Thank you all for your suggestions. This is the code I ended up using, and it works great:
opendir DIR, "." or die $!;
my @dirs = grep { /object...000/ && -d "$_" } readdir(DIR);
closedir DIR;
@dirs = sort @dirs;
my $highest = $dirs[-1];
print "highest: $highest\n";
$highest =~ s/object//g;
$highest += 1000;
my $limit = $highest + 10000;
($login,$pass,$uid,$gid) = getpwnam('apache')
or die "apache not in passwd file";
while ($highest < $limit) {
print "object$highest\n";
mkdir "object$highest";
chown $uid, $gid, "object$highest";
chmod 0777, "object$highest";
$highest += 1000;
}
Thanks again. | [reply] [d/l] |
|
|
print join ", ", sort 1 .. 10;
Prints:
1, 10, 2, 3, 4, 5, 6, 7, 8, 9
DWIM is Perl's answer to Gödel
| [reply] [d/l] [select] |
Re: how to create folders
by TOD (Friar) on Mar 28, 2007 at 08:16 UTC
|
opendir DIR, "the/base/directory" or die $!;
my @dirs = readdir DIR;
closedir DIR;
shift @dirs; # remove ..
shift @dirs; # and .
@dirs = sort @dirs;
my $highest = $dirs[-1];
$highest =~ s/\D//g;
$highest += 1000;
my $limit = $highest + 10000;
while ($highest < $limit) {
mkdir "object$highest";
$highest += 1000;
}
pretty simple ;) | [reply] [d/l] |
|
|
The two shifts are rather OS dependent and may cause a little grief if the code is run in a root directory. The code isn't very tolerant of foibles like unfortunately named files or directories - especially if they sort higher than the directories of interest.
Your while loop could be turned into a for loop:
my $start = ($highest / 1000) + 1;
mkdir "object${_}000" for $start .. $start + 9;
DWIM is Perl's answer to Gödel
| [reply] [d/l] |
|
|
Excellent, I only had to make some small modifications, like:
my @dirs = grep { /object...000/ && -d "$_" } readdir(DIR);
...
mkdir "object$highest";
chown $uid, $gid, "object$highest";
chmod 0777, "object$highest";
...
Thanks so much! | [reply] [d/l] |
|
|
You could do it somewhat smarter and extract just the numbers:
my @numbers = map /object(\d+)000/, grep -d, readdir(DIR);
You can even directly pull out the highest number by using max out of List::Util:
use List::Util 'max';
my $highest = max map /object(\d+)000/, grep -d, readdir(DIR);
And using glob instead of readdir can help you wead out the unwanted files before trying to process them, if there's a lot of other stuff in the directory you may be not interested in:
my $highest = max map /object(\d+)000/, grep -d, glob 'object???000';
| [reply] [d/l] [select] |
Re: how to create folders
by soliplaya (Beadle) on Mar 28, 2007 at 09:11 UTC
|
I don't know what your intended usage is, nor under which OS you're working, but if it happens that you intend to create lots of directories that way, I suggest that you try first to create a few thousand subdirectories in a directory, then check how your OS handles that in terms of directory access speed. You could be surprised.
Apart from that, I would also filter out the "dot" entries with a grep(), and not rely on the dot entries being first. I would do an explicit and careful sort() on the remaining entries, and then maybe just get the last item of the array (or the first, if you sorted descending).
Furthermore, I believe that there should be at least one Monk here that could do it all as a one-liner, but that's not me.
my $high = (sort( grep (!/^\.\.?$/, readdir(DIR))))[-1]
Mmmm ?
| [reply] [d/l] |