3

首先,我必须承认我是 Perl 的新手,所以我的问题对某些人来说可能看起来很垃圾,我很抱歉。我目前正在使用适用于 Perl 的 VMWare SDK,但我被困在我的上传功能上。我想做的是为每个 VMDK 生成一个唯一标识符(例如,我添加到 VM 的硬盘)。基本上,用户提供硬盘应该作为脚本的参数。

但是,如果用户选择了一个已经被占用的名字,我们就会遇到问题。我考虑了很多解决方案,比如添加时间戳(这将是唯一的),但我想要更优雅的东西。所以,让我们考虑一下:

@vmdks:列出所有已经在 VM 上的硬盘

$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,然后检索后者?

非常感谢,我希望我足够清楚

4

2 回答 2

0

您还可以使用智能匹配运算符进行匹配。我已经在 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($_);
}
于 2012-10-08T20:11:13.003 回答
0

你可以得到所有候选人的子数组:

my @tmp = grep(/^$filename-\d+/, @vmdks);

的最后一个元素@tmp将是最新的索引文件名$filename

于 2012-10-08T19:58:51.683 回答