Perl环坚持阅读的文件?
-
06-07-2019 - |
题
关闭这个问题。会喝的红牛。睡眠。代码然后回来带崭新的品牌问题有单元的测试案例。
更新:新的文件 在这里,
也配置文件 在这里,
我重构的代码再次:
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.
解决方案
此问题的最终发布:根据您的最新更新,我相信以下代码说明了使用/:/
作为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'
];
没有错误 ... 没有警告 因此,还有其他一些事情你坚持不向我们展示。
其他备注:
-
使用词法文件句柄,让perl告诉你它可能遇到的错误而不是假设。
-
在最小适用范围内声明变量。
-
当您可以在
$_
语句中执行此操作时,无需在循环体中将$conline
指定给while
。 -
在原始代码中,您没有在
@columns
中添加任何内容或使用$colData
执行任何有用的操作。 -
淡化这些言论。计算机按照GIGO的原则工作。
-
查看您发布的链接中的代码,看起来您不是意识到你可以这样做:
use File::Spec::Functions qw( catfile ); ... catfile($ETLSpliter::filepath_results, $ETLSpliter::actual_name);
醇>
此外,看起来你正在使用一个哈希就能完成这项工作的包:
$ETLSpliter{filepath}
最后,您确实认识到Spliter
不正确。 ITYM:Splitter
。
其他提示
你确定这是卡住?你从来不保存任何数据 @columns
, ,所以你的代码将总是返回的一个空洞的名单。
其他说明:
- 你的
die
呼叫中应包括$!
(操作系统误差)。还有其他的原因open
可能会失败,除非存在的文件,$!
会告诉你什么是真正的问题。 - 你可能应该做一个
chomp $conline
摆脱换行。 - 你可以做的
while (my $conline = <CFILE>)
而不是复制的价值从$_
. - 两个参数
open
(特别是隐性的<
模式)是贫穷的形式。使用三种参数形式(最好用一个词汇的文件句柄)是优选的:open(my $fh, '<', $filename) or die...
$ETLSpliter::name
中的内容 - 任何/
字符都应该被转义。
该片段中的许多其他问题已经解决,因此我不会去那里。
最终将其制作出来!!!!!哇睡觉真是太棒了。
反正。问题在于我的消息中的$ ETLSplitter :: configFile。
die ('Error opening '.$ETLSpliter::configFile.': '.$!);
哪个有winblows路径分隔符'/'。因为我用双引号输出,perl将路径中的'/'作为模式进行交错。从这里
die "Error opening some/path/to/ ...
到
... /=>/,
这与子程序中的整个程序流程相混淆。通过这样做解决了这个问题。
<*>