代码之家  ›  专栏  ›  技术社区  ›  kthakore

Perl循环在读取文件时卡住了吗?

  •  -1
  • kthakore  · 技术社区  · 17 年前

    here

    配置文件也是 here

    sub getColumns {
        open my $input, '<', $ETLSplitter::configFile
            or die "Error opening '$ETLSpliter::configFile': $!";
    
        my $cols;
        while( my $conline = <$input> ) {
            chomp $conline;
            my @values = split (/=>/, $conline);
            if ($ETLSplitter::name =~ $values[0] ) {
                $cols = $values[1];
                last;
            }
        }
    
        if($cols) {
            @ETLSplitter::columns = split (':', $cols);
        }
        else {
            die("$ETLSplitter::name is not specified in the config file");
        }
    }
    

    die("$ETLSplitter::name is not specified in the config file"); .

    split (':', $cols); split (/:/, $cols);

     perl -wle "
     use modules::ETLSplitter;
     \$test = ETLSplitter->new('cpr_operator_metric_actual_d2', 'frame/');
     \$test->prepareCSV();"
     syntax error at modules/ETLSplitter.pm line 154, near "}continue"
     Compilation failed in require at -e line 2.
     BEGIN failed--compilation aborted at -e line 2.
    
    4 回复  |  直到 17 年前
        1
  •  6
  •   Sinan Ünür    17 年前

    此问题的最终帖子: /:/ split

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use Data::Dumper;
    
    for my $varname ( qw( adntopr.cpr.smtref.actv cpr_operator_detail )) {
        print $varname, "\n";
        print Dumper get_columns(\*DATA, $varname);
    }
    
    sub get_columns {
        my ($input_fh, $varname) = @_;
    
        while ( my $line = <$input_fh> ) {
            chomp $line;
            my @values = split /=>/, $line;
            next unless $varname eq $values[0];
            return [ split /:/, $values[1] ];
        }
        return;
    }
    
    __DATA__
    adntopr.cpr.smtref.actv=>3:8:18:29:34:38:46:51:53:149
    adntopr.smtsale2=>3:8:16:22:27:37:39:47:52:57:62:82:102:120:138:234:239:244:249:250:259:262:277:282:287:289:304:319:327:331:335:339:340:341:342:353:364:375:386:397:408
    cpr_operator_detail=>3:11:18:28:124:220:228:324
    cpr_operator_org_unit_map=>7:12
    cpr_operator_metric_actual=>8:15:25:33:38:40:51
    
    C:\Temp> tjm
    adntopr.cpr.smtref.actv
    $VAR1 = [
              '3',
              '8',
              '18',
              '29',
              '34',
              '38',
              '46',
              '51',
              '53',
              '149'
            ];
    cpr_operator_detail
    $VAR1 = [
              '3',
              '11',
              '18',
              '28',
              '124',
              '220',
              '228',
              '324'
            ];
    

    鉴于您最近关于模式中正则表达式特殊字符的评论,如果要在模式中使用它们进行拆分,请确保引用它们。也有可能 $ETLSpliter::name 可能包含其他特殊字符。我修改了代码来处理这种可能性。

    sub getColumns {
        open my $input, '<', $ETLSpliter::configFile
              or die "Error opening '$ETLSpliter::configFile': $!");
          my @columns;
          while( my $conline = <$input> ) {
              my @values = split /=>/, $conline;
              print "not at: ".$conline;
              push @columns, $values[1] if $values[0] =~ /\Q$ETLSpliter::name/;
          }
          return @columns;
      }
    

    所以,模式确实是 /=>/ 根据您下面的评论。然后:

    my $conline = q{cpr_operator_detail=>3:11:18:28:124:220:228:324};
    my @values = split /=>/, $conline;
    
    use Data::Dumper;
    print Dumper \@values;
    __END__
    
    C:\Temp> tml
    $VAR1 = [
              'cpr_operator_detail',
              '3:11:18:28:124:220:228:324'
            ];
    

    ... 因此,还有一些事情正在发生,你坚持不向我们展示。

    1. 使用词法文件句柄,让perl告诉你它可能会遇到什么错误,而不是假设。

    2. 在最小的适用范围内声明变量。

    3. 无需分配 $_ $conline while 声明。

    4. 在原始代码中,您没有放入任何内容 @columns 或者做任何有用的事情 $colData .

    5. the link you posted ,看起来你不知道你可以做到:

      use File::Spec::Functions qw( catfile );
      ...
      catfile($ETLSpliter::filepath_results, $ETLSpliter::actual_name);
      

    $ETLSpliter{filepath}
    

    最后,你确实意识到 Spliter Splitter .

        2
  •  3
  •   Michael Carman    17 年前

    你确定它卡住了吗?您从不将任何数据存储在 @columns

    其他注意事项:

    • die 通话应包括 $! (操作系统错误)。还有其他原因 open $! 会告诉你真正的问题是什么。
    • 你可能应该做一个 chomp $conline
    • while (my $conline = <CFILE>) 而不是从复制值 $_ .
    • 打开 < mode)的形式很差。最好使用三参数形式(最好是带有词法文件句柄): open(my $fh, '<', $filename) or die...
        3
  •  1
  •   laalto    17 年前

    里面有什么 $ETLSpliter::name -任何 / 应该转义那里的字符。

    代码片段中的许多其他问题已经得到解决,所以我不会去那里。

        4
  •  0
  •   innaM    17 年前

    终于想通了!!!!!哇,睡眠是一种神奇的力量。

    die ('Error opening '.$ETLSpliter::configFile.': '.$!);
    

    其具有winblows路径分隔符“/”。因此,由于我以双引号输出,perl将路径中的“/”解释为模式。从这里

    die "Error opening some/path/to/ ...
    

    ...  /=>/,