0

現在、いくつかのスクリプトを csh から perl に翻訳しています。次のスイッチ コントロールを持つスクリプトを 1 つ見つけました。

#And now some control
set get_command = h
set finish = 0

while (1)

    switch ($get_command)
    case "h":
    case "H":
    set cine_command = ""

cat << EOF
Control synchronised cine by (case insensitive):
  A        - A view data
  B        - B view data
  a        - accelerate
  d        - decelerate
  r        - real time heart rate
  <num>    - rate (frames per second)
  i        - toggle interpolation
  s        - step through (may lose a little synchronisation)
  c        - continue (restart) after stepping
  y        - reverse direction
  h        - help (repeat this)
  f        - finish (quit)
  q        - quit (finish)
  <return> -  quit
EOF

    breaksw

    case "":
    case "f":
    case "F":
    case "q":
    case "Q":
        set cine_command = '-f'
        set finish = 1
    breaksw

    case "a":
        set cine_command = '-a'
    breaksw

    case "d":
    case "D":
        set cine_command = '-d'
    breaksw

    case "r":
        case "R":
        set cine_command = "-t $time_per_frame"
    breaksw

    case "i":
    case "I":
        set cine_command = '-i'
    breaksw

    case "s":
    case "S": 
        set cine_command = "-s"
    breaksw

    case "c":
    case "C":
        set cine_command = "-c"
    breaksw

    case "y":
    case "Y":
        set cine_command = "-y"
    breaksw

    case '[0-9]*':
        set cine_command = "-r $get_command"
    breaksw

    default:
        echo "$get_command ignored"
        set cine_command = ""
    endsw

    if ('$cine_command' != '') then
    select_tv $FIRST_TV
    cine $cine_command
    select_tv $SECOND_TV
    cine $cine_command
    endif

    #
    # If we're stopping then get out of this loop.
    #
    if ($finish) break

    echo -n "cine > "
    set get_command = $<

end

システムに Perl 5.8.8 をインストールしていますが、use Strict;これを使用すると、次の perl リリースで非推奨になる可能性があることがわかっています。次のことを試しました。

#Add some fine control to script
my $get_command = 'h';
my $finish = 0;
my $cine_command;

while(<>)
  {
      switch ($get_command)
      {

    case [hH] {$cine_command = "";}

    print STDOUT << 'END';
Control synchronised cine by (case insensitive):
  A        - A view data
  B        - B view data
  a        - accelerate
  d        - decelerate
  r        - real time heart rate
  <num>    - rate (frames per second)
  i        - toggle interpolation
  s        - step through (may lose a little synchronisation)
  c        - continue (restart) after stepping
  y        - reverse direction
  h        - help (repeat this)
  f        - finish (quit)
  q        - quit (finish)
  <return> -  quit
END

      case [fFqQ] 
        {
         $cine_command = '-f';
         $finish = 1;
         }

      case "a"
        {
         $cine_command = '-a';
        }

      case [dD]
        {
         $cine_command = '-d';
         }

      case [rR]
        {
         $cine_command = "-t $time_per_frame";
         }

      case [iI]
        {
         $cine_command = '-i';
         }

      case [sS]
        {
         $cine_command = '-s';
         }

      case [cC]
        {
         $cine_command = '-c';
         }

      case [yY]
        {
         $cine_command = '-y'
         }

      case /\d/
        {
         $cine_command = "-r $get_command";
        }

      else 
        {
          print "$get_command ignored\n";
          $cine_command = "";
          }

    if ($cine_command ne "") 
      {
        `select_tv $FIRST_TV`;
        `cine $cine_command`;
        `select_tv $SECOND_TV`;
        `cine $cine_command`;
      }

    exit if( $finish == 1);

    print STDOUT "cine > \n";
    chomp(my $get_command = <STDIN>);

      }


  }

Return キーを押すと、必要なオプションが端末に出力されます。ただし、STDIN に任意のオプション (a、h、d など) を入力すると、応答がありません。retirn に入ると、期待どおりに「h 無視されました」というメッセージが端末に出力されます。

何か案は?

4

3 に答える 3

2

新しいバージョンのPerlを入手すると言う人へ) :誰もが自分のシステムを制御できるわけではありません。OPがRedHat上にある場合、それはおそらく会社のマシンであり、OPがそれを制御できないことを意味します。RedhatでのPerlの最新リリースは5.8.8です。私たちはそれを古くて時代遅れだと考えるかもしれませんが、Perlの多くの企業バージョンはそれを使用しています。

私が管理しているローカルマシンには最新かつ最高のバージョンのPerlがありますが、Perl 5.8.8構文を使用して記述しなければならず、CPANモジュールをダウンロードできないと想定する必要があります。

これは実生活であり、それは吸うことができます。しかし、あなたはそれと一緒に暮らす必要があります...


まず、PerlとCshは完全に2つの言語であり、任意の言語を別の言語に行ごとに翻訳することはお勧めできません。Perlははるかに強力な言語であり、cshスクリプトを改善するために多くの機能を使用すると便利な場合があります。

コマンドラインを解析している場合は、モジュールGetopts :: Longの使用を検討してください。このモジュールは、多くの作業を実行し、Perl5.8.8で使用できます。これにより、switchステートメントで実行しようとしていることを正確に実行でき、作業量が大幅に削減され、柔軟性が大幅に向上します。

switchPerlでステートメントを使用することは避けます。それは本当にうまくいきませんでした。新しいgiven/whenものの方がうまく機能しますが、残念ながら、Perl5.10以降でのみ利用可能です。

代わりに、switchのものを忘れて、if/elsif構造体を使用してからcaseステートメントを使用してください。

my $usage =<<USAGE;
Control synchronised cine by (case insensitive):
  A        - A view data
  B        - B view data
  a        - accelerate
  d        - decelerate
  r        - real time heart rate
  <num>    - rate (frames per second)
  i        - toggle interpolation
  s        - step through (may lose a little synchronisation)
  c        - continue (restart) after stepping
  y        - reverse direction
  h        - help (repeat this)
  f        - finish (quit)
  q        - quit (finish)
  <return> -  quit
USAGE

$cine_command;
$finish;
while ( my $command = get_command() ) {
    if   ( $command =~ /^h$/i ) {
        print "$usage\n";
        exit 0;
    }
    elsif ( $command =~ /^(fq)$/i ) {
        $cine_command = '-f'
        $finish = 1
    }
    elsif ( $command =~ /^a$/i ) {
        $cine_command = '-a';
    }
    elsif ...

これはswitchステートメントほどエレガントではありませんが、機能を果たし、理解と保守が容易です。また、正規表現マッチングの使用を利用してください。たとえば、$command =~ /^(fq)$/i is checking to see if$ command is equal toF ,fqQ`をすべて同時に実行します,, or

于 2013-02-18T21:02:13.357 に答える
0

多くのオプションを持つより大きなプログラムのApp::Cmdのようなものを見るかもしれません。それ以外の場合、switch ステートメントではなく、サブリファレンスのハッシュが委任に対して機能する可能性があります。

于 2013-02-19T01:42:46.043 に答える
0

while(<>){}while(1)in perl はcshと同等ではありません。perl では、 which is a read と eof に達していないことを確認するチェックにwhile(<>)相当します。while(defined($_ = <>))に置き換えwhile(<>)てみてくださいwhile(1)

于 2013-02-18T17:34:19.703 に答える