| [reply] |
#!/usr/bin/perl
use warnings;
use strict;
use Path::Tiny;
use File::Find;
sub random_char {
my @allowed = @_;
return $allowed[ rand @allowed ]
}
sub random_name {
my ($length, @allowed) = @_;
return join q(), map random_char(@allowed), 1 .. $length
}
sub create_dirs {
my ($max_dirs, $max_length, $max_files, $depth, @characters) = @_;
my %dirs;
my $count_dirs = 1 + int rand $max_dirs;
while (keys %dirs < $count_dirs) {
my $dirname = random_name(1 + rand $max_length, @characters);
redo if -f $dirname;
undef $dirs{$dirname};
}
for my $dir (keys %dirs) {
path($dir)->mkpath;
chdir $dir;
my $count_files = 1 + int rand $max_files;
my %files;
undef $files{ random_name(1 + rand $max_length, @characters) }
while keys %files < $count_files;
path($_)->touch for keys %files;
if (int rand $depth) {
create_dirs($max_dirs, $max_length, $max_files,
$depth - 1, @characters);
}
chdir '..';
}
}
sub check {
my ($max_files, $max_dirs, $max_depth) = @_;
sub {
return unless -d $File::Find::name;
my @dirs = glob $File::Find::name . '/*/';
s=/$== for @dirs;
my %files;
undef @files{ glob $File::Find::name . '/*' };
delete @files{ @dirs };
my $count_files = keys %files;
my $count_dirs = @dirs;
my $depth = $File::Find::name =~ tr=/==;
die "Too many files in $File::Find::name: $count_files"
if $count_files > $max_files;
die "Too many dirs in $File::Find::name: $count_dirs"
if $count_dirs > $max_dirs;
die "Directory too deep: $File::Find::name " if $depth > $max_
+depth;
}
}
sub main {
my $max_depth = 5;
my $max_dirs = 4;
my $max_files = 5;
my $max_length = 4;
my @characters = ('A' .. 'Z', '0' .. '9', '_');
create_dirs($max_dirs, $max_length, $max_files, $max_depth, @chara
+cters);
find(check($max_files, $max_dirs, $max_depth), '.');
}
main();
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] [select] |
thanks a lot @choroba
and if i only create files on final depth ?
| [reply] |
Feel free to tweak the script to your liking.
Also, this is not Facebook, use [choroba] to refer to a monk (it still doesn't notify them, but makes their name clickable).
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] [select] |
File::Temp can be used to set up randomly generated path and filenames, and you can even request that they not be deleted on exit. But there has to be more to your question than that. Surely you aren't looking to write purely random directories and files into your filesystem. There must be a pattern you intend to follow. For example, git stores blobs by their SHA1 hash, where a file's content, length, and name are hashed to come up with a SHA id. The first two digits of that ID become a directory name, and the remainder of the digits of the SHA become the filename of the blob within that directory. That way there's a repeatable means of generating seemingly random filenames that are unlikely to collide, and put them in directories that are relatively evenly distributed.
Your question, as it stands, really fails to communicate your specific needs. However, there are times where a purely pseudo-random filename placed in a purely pseudo-random directory is useful, and for those times, File::Temp is the common solution.
| [reply] |