perl中无效的elsif循环

时间:2015-08-12 12:50:48

标签: perl awk sed

此Perl程序将* .mdp文件作为输入,并生成该文件的副本,并更改​​为init_lambdaforeign_Lambda

Lambda从01不等。参数foreign lambda包含两个值,具体取决于间距,例如如果λ= 0.1且间距为0.05,那么外来λ值将为0.05和0.1

但我想以不同方式打印foreign lambdaLower_Lambda的{​​{1}}值。我使用了一个条件语句但我无法理解为什么第二个Higher_Lambda条件,即elsif没有被执行。

如果我可以使用sed或awk实现这一点,请建议

elsif ($i == $Higher_Lambda)


输入文件

#!/usr/bin/perl -w

use strict;

# opens a generic .mdp file and replaces the values of
# 'init_lambda' and 'foreign_lambda' values at increments
# of by spacing

my $Lower_Lambda  = 0.1;
my $Higher_Lambda = 0.2;
my $Count         = 5;
my $init_spacing  = 0.05;

unless ( @ARGV ) {
    die "Usage: $0 input.mdp\n";
}

my $difference = $Higher_Lambda - $Lower_Lambda;
my $spacing    = $difference / $Count;
my $mdp        = $ARGV[0];
my @temp       = split( '\.', $mdp );
my $base       = $temp[0];

open( IN, "<$mdp" );
my @in = <IN>;
close( IN );

for ( my $i = $Lower_Lambda ; $i < $Higher_Lambda ; $i += $spacing ) {

    my $filename = "${base}_${i}.mdp";
    open( OUT, ">$filename" );

    foreach $_ ( @in ) {

        unless ( ( $_ =~ /^init_lambda/ ) || ( $_ =~ /^foreign_lambda/ ) ) {
            print OUT $_;
        }

        if ( $_ =~ /^init_lambda\s*=/ ) {

            if ( $i < 1 ) {
                printf OUT "%s %0.3f\n", $&, $i;
            }
            else {
                printf OUT "%s %.3f\n", $&, $i;
            }
        }

        if ( $_ =~ /^foreign_lambda\s*=/ ) {

            if ( $i < 1 ) {

                if ( $i == 0 ) {
                    printf OUT "%s %0.3f\n", $&, ( $i + $spacing );

                    print "I am in 0";
                }
                elsif ( $i == $lower_lambda ) {

                    printf OUT "%s %0.3f %0.3f\n", $&, $i - $init_spacing,
                      ( $i + $spacing );
                    print "I am not there";
                }
                elsif ( $i == $Higher_Lambda ) {

                    printf OUT "%s %0.3f %0.3f\n", $&, $i - $spacing,
                      $i + $init_spacing;
                    print "I am here bro";
                }
                else {

                    printf OUT "%s %0.3f %0.3f\n", $&, ( $i - $spacing ),
                      ( $i + $spacing );

                }
            }
            else {
                printf OUT "%s %0.3f\n", $&, ( $i - $spacing );
            }
        }
    }

    close( OUT );

}

exit;

2 个答案:

答案 0 :(得分:0)

我担心我无法理解你所提到的内容的逻辑,但很可能你的问题与比较浮点值是否相等有关。你应该从不做,因为浮点表示的精度有限

相反,您应该使用整数计数器,并从中计算lambda值。在我的下面的代码中,我已经将$i从0重复到$count,然后使用

计算相应的$lambda
my $lambda = $lower_lambda + $i * $difference / $count;

然后,您可以将$i与0和$count进行比较,以检查您是在第一步还是最后一步

我无法知道范围是否正确(应该$i停在$count还是$count-1?)但该计算肯定是正确的

我关注你的考试$i== 0$i < 1,因为他们几乎肯定会失败,但我无法看到你正在尝试做什么。第一种情况只能在$lower_lambda为负或为零且$upper_lambda为正或零时出现,这似乎不太可能。我怀疑这些测试是多余的,可能是尝试让你的代码工作?

并且不要使用大写字母作为词汇变量:它们是为包名称之类的全局标识符保留的,并且将它们用于普通变量可能会让你无可救药地混淆

此代码正确运行并创建文件序列,但您应仔细检查内容

#!/usr/bin/perl

use strict;
use warnings;
use v5.10.1;
use autodie;

our @ARGV = 'Lower_Lambda.mdp';

die "Usage: $0 input.mdp\n" unless @ARGV;

my $mdp = $ARGV[0];

my $lower_lambda  = 0.1;
my $higher_lambda = 0.2;
my $count         = 5;
my $init_spacing  = 0.05;

my $difference = $higher_lambda - $lower_lambda;
my $spacing    = $difference / $count;

for my $i ( 0 .. $count ) {

    my $lambda = $lower_lambda + $i * $difference / $count;

    my $filename = $mdp =~ s/.*\.\K/sprintf '_%0.3f', $lambda/er;    #/

    open my $in_fh,  '<', $mdp;
    open my $out_fh, '>', $filename;

    while ( <$in_fh> ) {

        if ( /^(init_lambda\s*=\s*)/ ) {

            my $label = $1;

            printf $out_fh $label . "%0.3f\n",
                $lambda;
        }
        elsif ( /^(foreign_lambda\s*=\s*)/ ) {

            my $label = $1;

            if ( $lambda >= 1 ) {
                printf $out_fh $label . "%0.3f\n",
                    $lambda - $spacing;
            }
            elsif ( $lambda == 0 ) {
                printf $out_fh $label . "%0.3f\n",
                    $lambda + $spacing;
            }
            elsif ( $i == 0 ) {
                printf $out_fh $label . "%0.3f %0.3f\n",
                  $lambda - $init_spacing,
                  $lambda + $spacing;
            }
            elsif ( $i == $count ) {
                printf $out_fh $label . "%0.3f %0.3f\n",
                  $lambda - $spacing,
                  $lambda + $init_spacing;
            }
            else {
                printf $out_fh $label . "%0.3f %0.3f\n",
                  $lambda - $spacing,
                  $lambda + $spacing;
            }

        }
        else {
            print $out_fh $_;
        }
    }

    close $out_fh;
}

答案 1 :(得分:0)

关于你的上一个问题谁不重复

if(LAMBDA == 0.95  || ( LAMBDA > 0.96 && LAMBDA <1.01  ))

           LAMBDA += 0.05;

    else

           LAMBDA += 0.1;