首先,我必须承认我是Perl的新手,所以对于某些人来说,我的问题可能看起来很糟糕,我很抱歉。我目前正在使用用于Perl的VMWare SDK,我仍然坚持上传功能。我想做的是为每个VMDK生成一个唯一的标识符(例如我添加到VM的硬盘)。基本上,用户提供硬盘应作为脚本的参数。
但是,如果用户选择已经采用的名称,则会出现问题。我想过很多解决方案,比如添加时间戳(这将是独一无二的),但我想要更优雅的东西。那么,让我们考虑一下:
@vmdks :列出虚拟机上已有的所有硬盘
$ filename :用户想要提供给VMDK的名称,一旦它在VM上
$ target :硬盘实际上具有的名称。
我想要像filename-00X这样的东西,其中X是出现的。因此,例如,如果有人试图添加名为“FOO”的硬盘,当一个已存在时,它将被重命名为“FOO-001”。请注意,用户只能输入带有字母数字字符的磁盘名称,因此他不能将硬盘命名为“FOO-001”,这样可以避免冲突。
因为我不太了解Perl,所以我决定用伪代码编写它,希望你不介意:
IF $filename IS IN @vmdks
# So here we have a conflict
IF $filename-X IS IN @vmdks
# X should be a 3-digit number, like 001, 002, 666, etc.
INDEX := X
INDEX++
$target = $filename-INDEX
ELSE
$target = $filename-001
ENDIF
ELSE
$target = $filename
ENDIF
我想我可以通过以下方式轻松完成第一个条件:
if(grep{$_ eq $filename} @vmdks) ...
但第二个......我真的被卡住了:/我怎么能匹配$ filename-index,然后检索后者呢?
非常感谢,我希望我足够清楚
答案 0 :(得分:0)
您可以将所有候选人的子阵列视为:
my @tmp = grep(/^$filename-\d+/, @vmdks);
,@tmp
的最后一个元素将是$filename
的最新索引文件名
答案 1 :(得分:0)
您也可以使用smart-match operator进行匹配。我已经在Perl中完成了伪代码,只需稍微调整一下你的算法。
请注意有多种方法可以做到这一点。您还可以使用哈希进行查找。这将更快丢失,但消耗更多的内存。这取决于任务,这是最好的选择。
#!/usr/bin/perl
use strict; use warnings;
use feature qw(say);
my @vmdks = qw( foo bar dilbert dilbert-001 );
sub test_filename {
my ($filename) = @_;
# abort if the filename is not alphanumeric
return if $filename =~ /\W/;
# check if the filename is in our list
if ($filename ~~ @vmdks) {
my $i = 1; # counter, starting at 1
# check if the extended filename is in the list
while ( sprintf('%s-%03d', $filename, $i) ~~ @vmdks ) {
$i++; # increment
}
# assign the new filename
$filename = sprintf('%s-%03d', $filename, $i);
}
return $filename;
}
# test ist
for (qw ( phb dilbert foo foo bar dogbert bar foo 1234 123) ) {
say test_filename($_);
}