Apache 2.2.11版(Unix) 架构x86_64 操作系统Linux 内核版本2.6.18-164.el5
好的,这就是我的工作。但是,我可能没有在脚本的其余部分中使用File::Util
来执行任何其他操作。
我的目录名是8位数,起始于10000000。
我将最高找到的数字与stat last created
作为双重检查进行比较,但是我相信它有点过分了。
另一个问题是我不知道如何在list_dir
命令中使用正则表达式,因此只有8位数字,例如m!^([0-9]{8})\z!x)
可以驻留在该字符串中。读这个男人,这个例子是...... '--pattern=\.txt$')
,但是,我的徒劳尝试:'--pattern=m!^([0-9]{8})\z!x)')
嗯,就是这样。
那么,有没有“更好”的方法来获取最新的文件夹/目录?
use File::Util;
my($f) = File::Util->new();
my(@dirs) = $f->list_dir('/home/accountname/public_html/topdir','--no-fsdots');
my @last = (sort { $b <=> $a } @dirs);
my $new = ($last[0]+1);
print "Content-type: text/html\n\n";
print "I will now create dir $new\n";
而且..我怎么会忽略任何与我的正则表达不匹配的东西?
我认为答案可能也存在于ls -d
中,但作为初学者,我不熟悉来自脚本的系统调用(如果事实上那将是什么?;-))。
更具体地说:
打开目录的最佳方法,返回该目录中最新的8位数目录的名称,忽略其他所有目录。将8位数的目录名称增加1并创建新目录。
最有效的是:stat
或实际的8位数文件名。 (目录名称无论哪种方式都是8位数。)最好使用File::Util
还是只是内置Perl调用?
答案 0 :(得分:3)
您希望有多少个目录?您在任何目录中拥有的条目越多,获得的速度就越慢。你应该制定一个方案,你可以将一些东西散列到一个扩展文件的目录结构中,这样就没有目录可以容纳那么多项。比如,你有了名字'0123456789',你创建了如下目录结构:
0/01/0123456789
您可以拥有任意数量的目录级别。例如,请参阅CPAN的目录结构。我的作者姓名是BDFOY,所以我的作者目录是authors / id / B / BD / BDFOY。这样就没有任何目录有大量条目(除非您的作者ID是ADAMK或RJBS)。
您还有一个潜在的争用问题需要解决。在您发现最新版本的时间和尝试创建下一个版本的时间之间,您可能已经创建了目录。
至于手头的任务,如果你要拥有一百万个目录,我想我会向system
寻找。有类似的东西:
ls -t -d -1 [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -1
对于此任务,我认为你不会比ls
更快。如果有大量的目录,那么你自己必须完成的所有工作都应该超过分支的成本。
答案 1 :(得分:1)
打开目录的最佳方式,返回该目录中最新8位数目录的名称,忽略其他所有目录。将8位数的目录名称增加1并创建新目录。哪个最有效:统计或实际的8位数文件名?
首先,我应该指出,在目录中拥有大约100,000,000个子目录可能效率很低。
如何只获得包含八位数的目录名?
use File::Slurp;
my @dirs = grep { -d and /\A[0-9]{8}\z/ } read_dir $top;
你如何获得最大的?
use List::Util qw( max );
my $latest = max @dirs;
现在,问题是,在确定$latest
和创建目录的尝试之间,其他一些进程可以创建相同的目录。所以,我会使用$latest
作为起点,并继续尝试创建下一个目录,直到我成功或用完数字。
#/usr/bin/perl
use strict;
use warnings;
use File::Slurp;
use File::Spec::Functions qw( catfile );
use List::Util qw( max );
sub make_numbered_dir {
my $max = 100_000_000;
my $top = '/home/accountname/public_html/topdir';
my $latest = max grep { /\A[0-9]{8}\z/ } read_dir $top;
while ( ++$latest < $max ) {
mkdir catfile($top, sprintf '%8.8d', $latest)
and return 1;
}
return;
}
如果你按照我最初推荐的方式尝试,你会多次调用mkdir
。
至于如何使用File::Util::list_dir
过滤条目:
#/usr/bin/perl
use strict;
use warnings;
use File::Util;
my $fu = File::Util->new;
print "$_\n" for $fu->list_dir('.',
'--no-fsdots',
'--pattern=\A[0-9]{8}\z'
);
C:\Temp> ks 10001010 12345678
但是,我必须指出,在我花费的几分钟内,我不太喜欢这个模块,特别是模块作者对在列表上下文中调用方法和函数的痴迷。我不认为我会再次使用它。