【发布时间】:2015-12-20 22:26:12
【问题描述】:
编辑:修改代码和输出使其更清晰
编辑 2:添加了用于复制的示例输入
我有一个 JSON 文件和一个 CSV 文件,我正在对两者进行比较。问题是 $asset_ip 在外部 foreach 循环中被正确定义,但是在嵌套循环中 $asset_ip 变得未定义。
为什么 $asset_ip 变得未定义?
#!/usr/bin/perl
# perl -e'use CPAN; install "Text::CSV"'
use strict;
use warnings;
use JSON::XS;
use File::Slurp;
use Text::CSV;
my $csv = Text::CSV->new( { sep_char => ',' } );
my $csv_source = "servers.csv";
my $json_source = "assets.json";
my $dest = "servers_for_upload.csv";
# defined these here as I need to use them in foreach loop and if statement:
my $csv_ip;
my @fields;
open( my $csv_fh, '<', $csv_source ) or die "$! error trying to read";
open( my $dest_fh, '>', $dest ) or die "$! error trying to read";
my $json = read_file($json_source);
my $json_array = decode_json $json;
foreach my $item (@$json_array) {
my $id = $item->{id};
my $asset_ip = $item->{interfaces}->[0]->{ip_addresses}->[0]->{value};
# test the data is there:
if ( defined $asset_ip ) {
print "id: " . $id . "\nip: " . $asset_ip . "\n";
}
while (my $line = <$csv_fh>) {
chomp $line;
if ( $csv->parse($line) ) {
@fields = $csv->fields();
$csv_ip = $fields[0];
}
else {
warn "Line could not be parsed: $line\n";
}
if ( $csv_ip eq $asset_ip ) {
# preppend id to csv array and write these lines to new file
unshift( @fields, $id );
print $dest_fh join( ", ", @fields );
}
}
}
close $csv_fh;
输出:
Use of uninitialized value $asset_ip in string eq at script.pl line 43, <$csv_fh> line 1.
Use of uninitialized value $asset_ip in string eq at script.pl line 43, <$csv_fh> line 2.
Use of uninitialized value $asset_ip in string eq at script.pl line 43, <$csv_fh> line 3.
id: 1003
ip: 192.168.0.2
id: 1004
ip: 192.168.0.3
id: 1005
ip: 192.168.0.4
assets.json:
[{"id":1001,"interfaces":[]},{"id":1003,"interfaces":[{"ip_addresses":[{"value":"192.168.0.2"}]}]},{"id":1004,"interfaces":[{"ip_addresses":[{"value":"192.168.0.3"}]}]},{"id":1005,"interfaces":[{"ip_addresses":[{"value":"192.168.0.4"}]}]}]
请注意,对于第一次迭代,$asset_ip 将未定义。因此,如果定义了 $asset_ip,我将更改代码以仅运行 eq 比较。但是,对于这个示例,我没有进行检查,因为所有迭代都是未定义的。
servers.csv:
192.168.0.3,Brian,Germany
192.168.0.4,Billy,UK
192.168.0.5,Ben,UK
【问题讨论】:
-
与您的问题无关:
die '$! error trying to read'中应该有双引号,而不是单引号。照原样,如果发生这些错误,您将得到$!而不是变量的值。 -
抱歉 - 没有提到 - 我在运行脚本时收到 $asset_ip 未定义的错误。
-
引用错误消息(和行号)有助于诊断。一些示例源数据也是如此。大概这是您正在使用的JSON? stackoverflow.com/questions/32737301/…您有一些示例 CSV 数据吗?
-
我认为没有必要包含样本数据。简单地说,$asset_ip 在外循环中被定义为一个 ip 地址,但是一旦在内循环中它是未定义的。第二个循环针对 CSV 文件中的行数迭代正确的次数。
-
没有样本数据,我们无法重现问题,因此只能猜测是哪条线路造成的,以及如何造成的。这就是我们通常请求minimal reproducible example 的原因 - 没有明确的原因为什么它变得未定义或 在哪里 它变得未定义。但是在阅读/重新阅读
$csv_fh时存在明显的逻辑错误。