【问题标题】:Perl - Generating Unique IdentifiersPerl - 生成唯一标识符
【发布时间】:2012-10-08 19:44:50
【问题描述】:

首先,我必须承认我是 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,然后检索后者?

非常感谢,希望我说的够清楚了

【问题讨论】:

    标签: arrays perl contains


    【解决方案1】:

    您也可以使用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($_);
    }
    

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2011-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-20
        • 1970-01-01
        • 1970-01-01
        • 2017-12-06
        相关资源
        最近更新 更多