如何在 Perl 中解决此警告
How to resolve this warning in Perl
我问过这类问题previously但没有提供完整的代码。
我正在阅读下面的文件并检查每列中存在的最大字宽,然后将其以适当的对齐方式写入另一个文件。
id0 id1 id2 batch
0 34 56 70
2 3647 58 72 566
4 39 616 75 98 78 78987 9876 7899 776
89 40 62 76
8 42 64 78
34 455 544 565
我的代码:
unlink "temp1.log";
use warnings;
use strict;
use feature 'say';
my $log1_file = "log1.log";
my $temp1 = "temp1.log";
open(IN1, "<$log1_file" ) or die "Could not open file $log1_file: $!";
my @col_lens;
while (my $line = <IN1>) {
my @fs = split " ", $line;
my @rows = @fs ;
@col_lens = map (length, @rows) if $.==1;
for my $col_idx (0..$#rows) {
my $col_len = length $rows[$col_idx];
if ($col_lens[$col_idx] < $col_len) {
$col_lens[$col_idx] = $col_len;
}
};
};
close IN1;
open(IN1, "<$log1_file" ) or die "Could not open file $log1_file: $!";
open(tempp1,"+>>$temp1") or die "Could not open file $temp1: $!";
while (my $line = <IN1>) {
my @fs = split " ", $line;
my @az;
for my $h (0..$#fs) {
my $len = length $fs[$h];
my $blk_len = $col_lens[$h]+1;
my $right = $blk_len - $len;
$az[$h] = (" ") . $fs[$h] . ( " " x $right );
}
say tempp1 (join "|",@az);
};
我的警告
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 3.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
我得到了正确的输出,但不知道如何删除这个警告。
您收到 uninitialized
警告是因为,在检查 $col_lens[$col_idx] < $col_len
条件时,其中一个或两个是 undef
.
解决方案一:
您可以使用 next
语句跳过检查此条件。
for my $col_idx (0..$#rows) {
my $col_len = length $rows[$col_idx];
next unless $col_lens[$col_idx];
if ($col_lens[$col_idx] < $col_len) {
$col_lens[$col_idx] = $col_len;
}
}
解决方案 2:(不建议):
您只需将此行放在脚本顶部即可忽略 Use of uninitialized value..
警告。这将禁用块中的 uninitialized
个警告。
no warnings 'uninitialized';
更多信息,请参考此link
$col_idx
最多可以是一行中的字段数减一。对于第三行,这比 @col_lens
的最高索引要多,它最多包含 3 个元素。所以做以下是没有意义的:
if ($col_lens[$col_idx] < $col_len) {
$col_lens[$col_idx] = $col_len;
}
替换为
if (!defined($col_lens[$col_idx]) || $col_lens[$col_idx] < $col_len) {
$col_lens[$col_idx] = $col_len;
}
有了这个,就真的没有必要再检查 $. == 1
了。
以下代码演示了解决此任务的众多可能方法之一
- 逐行阅读
- 获取每个字段的长度
- 与之前存储的比较
- 调整到最大长度
- 形成
$format
打印字符串
- 打印格式化数据
use strict;
use warnings;
use feature 'say';
my(@data,@length,$format);
while ( <DATA> ) {
my @e = split ' ';
my @l = map{ length } @e;
$length[$_] = ($length[$_] // 0) < $l[$_] ? $l[$_] : $length[$_] for 0..$#e;
push @data,\@e;
}
$format = join ' ', map{ '%'.$_.'s' } @length;
$format .= "\n";
for my $row ( @data ) {
printf $format, map { $row->[$_] // '' } 0..$#length;;
}
__DATA__
id0 id1 id2 batch
0 34 56 70
2 3647 58 72 566
4 39 616 75 98 78 78987 9876 7899 776
89 40 62 76
8 42 64 78
34 455 544 565
输出
id0 id1 id2 batch
0 34 56 70
2 3647 58 72 566
4 39 616 75 98 78 78987 9876 7899 776
89 40 62 76
8 42 64 78
34 455 544 565
我问过这类问题previously但没有提供完整的代码。
我正在阅读下面的文件并检查每列中存在的最大字宽,然后将其以适当的对齐方式写入另一个文件。
id0 id1 id2 batch
0 34 56 70
2 3647 58 72 566
4 39 616 75 98 78 78987 9876 7899 776
89 40 62 76
8 42 64 78
34 455 544 565
我的代码:
unlink "temp1.log";
use warnings;
use strict;
use feature 'say';
my $log1_file = "log1.log";
my $temp1 = "temp1.log";
open(IN1, "<$log1_file" ) or die "Could not open file $log1_file: $!";
my @col_lens;
while (my $line = <IN1>) {
my @fs = split " ", $line;
my @rows = @fs ;
@col_lens = map (length, @rows) if $.==1;
for my $col_idx (0..$#rows) {
my $col_len = length $rows[$col_idx];
if ($col_lens[$col_idx] < $col_len) {
$col_lens[$col_idx] = $col_len;
}
};
};
close IN1;
open(IN1, "<$log1_file" ) or die "Could not open file $log1_file: $!";
open(tempp1,"+>>$temp1") or die "Could not open file $temp1: $!";
while (my $line = <IN1>) {
my @fs = split " ", $line;
my @az;
for my $h (0..$#fs) {
my $len = length $fs[$h];
my $blk_len = $col_lens[$h]+1;
my $right = $blk_len - $len;
$az[$h] = (" ") . $fs[$h] . ( " " x $right );
}
say tempp1 (join "|",@az);
};
我的警告
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 3.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
我得到了正确的输出,但不知道如何删除这个警告。
您收到 uninitialized
警告是因为,在检查 $col_lens[$col_idx] < $col_len
条件时,其中一个或两个是 undef
.
解决方案一:
您可以使用 next
语句跳过检查此条件。
for my $col_idx (0..$#rows) {
my $col_len = length $rows[$col_idx];
next unless $col_lens[$col_idx];
if ($col_lens[$col_idx] < $col_len) {
$col_lens[$col_idx] = $col_len;
}
}
解决方案 2:(不建议):
您只需将此行放在脚本顶部即可忽略 Use of uninitialized value..
警告。这将禁用块中的 uninitialized
个警告。
no warnings 'uninitialized';
更多信息,请参考此link
$col_idx
最多可以是一行中的字段数减一。对于第三行,这比 @col_lens
的最高索引要多,它最多包含 3 个元素。所以做以下是没有意义的:
if ($col_lens[$col_idx] < $col_len) {
$col_lens[$col_idx] = $col_len;
}
替换为
if (!defined($col_lens[$col_idx]) || $col_lens[$col_idx] < $col_len) {
$col_lens[$col_idx] = $col_len;
}
有了这个,就真的没有必要再检查 $. == 1
了。
以下代码演示了解决此任务的众多可能方法之一
- 逐行阅读
- 获取每个字段的长度
- 与之前存储的比较
- 调整到最大长度
- 形成
$format
打印字符串 - 打印格式化数据
use strict;
use warnings;
use feature 'say';
my(@data,@length,$format);
while ( <DATA> ) {
my @e = split ' ';
my @l = map{ length } @e;
$length[$_] = ($length[$_] // 0) < $l[$_] ? $l[$_] : $length[$_] for 0..$#e;
push @data,\@e;
}
$format = join ' ', map{ '%'.$_.'s' } @length;
$format .= "\n";
for my $row ( @data ) {
printf $format, map { $row->[$_] // '' } 0..$#length;;
}
__DATA__
id0 id1 id2 batch
0 34 56 70
2 3647 58 72 566
4 39 616 75 98 78 78987 9876 7899 776
89 40 62 76
8 42 64 78
34 455 544 565
输出
id0 id1 id2 batch
0 34 56 70
2 3647 58 72 566
4 39 616 75 98 78 78987 9876 7899 776
89 40 62 76
8 42 64 78
34 455 544 565