3

まず第一に、私はPerlを初めて使用することを認めなければならないので、私の質問は一部の人にとってはかなりごちゃごちゃしているように見えるかもしれません。申し訳ありません。現在、VMWare SDK for Perlを使用していますが、アップロード機能が停止しています。私がやりたいのは、VMDKごとに一意の識別子を生成することです(たとえば、VMに追加するハードディスク)。基本的に、ユーザーはハードディスクがスクリプトのパラメーターとして持つべきであると提供します。

ただし、ユーザーがすでに使用されている名前を選択した場合は問題が発生します。タイムスタンプ(一意)を追加するなど、多くの解決策を考えましたが、もっとエレガントなものが欲しいです。だから、考えてみましょう:

@vmdks:すでにVM上にあるすべてのハードディスクを一覧表示します

$ filename:VM上にあるときにユーザーがVMDKに付けたい名前

$ 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) ...

しかし、2番目のもの...私は本当に立ち往生しています:/ $ filename-indexと一致させて、後者を取得するにはどうすればよいですか?

どうもありがとうございました、私は十分に明確だったと思います

4

2 に答える 2

0

すべての候補のサブ配列を次のように取得できます。

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

の最後の要素は、@tmpの最新のインデックス付きファイル名になります$filename

于 2012-10-08T19:58:51.683 に答える
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 に答える