我有一个 CSV 文件,其中包含如下数据:
我想从上面的 csv 文件中解析数据并将其最初存储在哈希中。所以我的哈希转储器 %hash
看起来像这样:
$VAR1 = {
'1' => {
'Name' => 'Name1',
'Time' => '7/2/2020 11:00'
'Cell' => 'NCell1',
'PMR' => '1001',
'ISD' => 'ISDVAL1',
'PCO' => 'PCOVAL1'
},
'2' => {
'Name' => 'Name2',
'Time' => '7/3/2020 13:10',
'Cell' => 'NCell2',
'PMR' => '1002',
'PCO' => 'PCOVAL2',
'MKR' => 'MKRVAL2',
'STD' => 'STDVAL2'
},
'3' => {
'Name' => 'Name3',
'Time' => '7/4/2020 20:15',
'Cell' => 'NCell3',
'PMR' => '1003',
'ISD' => 'ISDVAL3',
'MKR' => 'MKRVAL3'
},
};
脚本如下:
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
use Data::Dumper;
my %hash;
my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1 });
open my $fh, "<:encoding(utf8)", "input_file.csv" or die "input_file.csv: $!";
while (my $row = $csv->getline ($fh)) {
my @fields = @$row;
$hash{$fields[0]}{"Time"} = $fields[1];
$hash{$fields[0]}{"Name"} = $fields[2];
$hash{$fields[0]}{"Cell"} = $fields[3];
}
close $fh;
print Dumper(\%hash);
此处 id
是每一行中的关键元素,根据数据值,每个数据应存储在 id 的相应名称中。
这里的问题是,直到 D 列(Cell
)我能够解析上面脚本中的数据,并且在 D 列之后不会有标题行,就像 E 列一样充当标题,F 列是特定标题的特定 ID 的值。类似的情况适用于其余数据值,直到结束。在中间我们可以看到一些值也会丢失。例如,id 1 没有 MKR
值。
我如何解析这些数据并将其存储在散列中,以便我的散列看起来像上面那样。 TIA。
最佳答案
对发布的脚本所做的更改是删除标题行,使其不构成结果的一部分,并添加了一个 for 循环以设置数据的重置。
使用的测试数据:
id,Time,Name,Cell,,,,,
1,7/2/2020 11:00,Name1,NCell1,PMR,1001,ISD,ISDVAL1
2,7/3/2020 13:10,Name2,NCell3,PMR,1002,PCO,PCOVAL2,MKR,MKRVAL2
更新的脚本:(这是第一个版本,建议在编辑中使用改进的版本)
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
use Data::Dumper;
my %hash;
my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1 });
open my $fh, "<:encoding(utf8)", "input_file.csv" or die "input_file.csv: $!";
my $headers = $csv->getline ($fh);
while (my $row = $csv->getline ($fh)) {
$hash{$row->[0]}{Time} = $row->[1];
$hash{$row->[0]}{Name} = $row->[2];
$hash{$row->[0]}{Cell} = $row->[3];
for (my $i = 4; $i < scalar (@{$row}); $i += 2) {
$hash{$row->[0]}{$row->[$i]} = $row->[$i + 1];
}
}
close $fh;
print Dumper(\%hash);
输出:
$VAR1 = {
'2' => {
'MKR' => 'MKRVAL2',
'Name' => 'Name2',
'PCO' => 'PCOVAL2',
'Cell' => 'NCell3',
'Time' => '7/3/2020 13:10',
'PMR' => '1002'
},
'1' => {
'Name' => 'Name1',
'ISD' => 'ISDVAL1',
'Cell' => 'NCell1',
'Time' => '7/2/2020 11:00',
'PMR' => '1001'
}
};
编辑:
感谢@choroba 的评论,这里是脚本的改进版本,首先使用所有附加行值设置哈希,然后使用从文件。
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
use Data::Dumper;
my %hash;
my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1 });
open my $fh, "<:encoding(utf8)", "input_file.csv" or die "input_file.csv: $!";
my $headers = $csv->getline ($fh);
while (my $row = $csv->getline ($fh)) {
$hash{$row->[0]} = { @$row[4 .. $#$row] };
@{$hash{$row->[0]}}{@$headers[1, 2, 3]} = @$row[1, 2, 3];
}
close $fh;
print Dumper(\%hash);
关于csv - 读取CSV解析数据并存储在Hash中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62710900/