动态循环在每次迭代时输出相同的内容

时间:2014-06-04 15:13:42

标签: perl loops for-loop

我正在尝试编写一个脚本来自动化一些数据收集。最初,该脚本运行由系统执行的一系列命令。这些命令的输出存储在两个文本文件中。在数据收集之后,我试图实现一个for循环,以便生成第三个输出文件,该文件列出输出1的第一行和输出的第二行的感兴趣的值,以及相对误差。以下代码完成正确的次数,但在所有四行上返回相同的值。我怀疑这与filehandler变量有关,但我不确定如何解决这个问题。

 for($ln = 1; $ln<5;$ln++){

    open($fh, '<',"theoretical.dat",<$ln>)
         or die "Could not open file 'theoretical.dat' $!";
    @line = split(' ',<$fh>);
    $v = $line[3];

    open($fh2, '<',"actual.dat",<$ln>)
         or die "Could not open file 'actual.dat' $!";
    @line = split(' ',<$fh2>);
    $v0 = $line[3];

    $e = abs(($v0-$v)/$v0);

   $rms = $rms + $e^2;

    my @result = ($v, $v0, $e);

    print  "@result \n";
                         }

输出文件代码已被省略。它包含if / else,具体取决于输出是否应通过管道输入到results.dat或附加。

请注意,有问题的数据每行存储4个数字,我希望使用此脚本访问其中的第4个数字。从生成的输出看来,$ ln在每次迭代后都会相应地发生变化,但是正在读取的行尽管在open命令中指示读取行号$ ln。

我在每个循环后尝试取消$ fh和$ fh2,但它仍然输出相同的。

1 个答案:

答案 0 :(得分:1)

您无法在open来电中指定文件的行号。实际上,重新打开文件会导致从顶部开始再次读取它。

如果没有看到你的数据文件,我无法确定,但我认为你想要这样的东西。

请注意,您可以use autodie而不是为open成功编码显式测试。您还必须use strictuse warnings作为每个Perl程序的顶部,并使用my声明所有变量尽可能接近其第一个使用点。我在这里循环声明$rms,这样它就可以累积一个总和的平方和,而不是每次循环时都被销毁和重新创建。

use strict;
use warnings;
use autodie;

open my $theo_fh, '<', 'theoretical.dat';
open my $act_fh,  '<', 'actual.dat';

my $rms;

for my $ln (1 .. 5) {

  my $v_theo = (split ' ', <$theo_fh>)[3];
  my $v_act  = (split ' ', <$act_fh>)[3];

  my $e   = abs(($v_act - $v_theo) / $v_act);
  my $rms = $rms + $e ^ 2;

  my @result = ($v_theo, $v_act, $e);
  print "@result\n";
}