csv - 读取CSV解析数据并存储在Hash中

标签 csv perl hash

我有一个 CSV 文件,其中包含如下数据:

enter image description here

我想从上面的 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/

相关文章:

python - 无法打开在Python代码中创建的Excel文件

perl - 在 Perl 中,如何检查文件是否被锁定?

perl - 我可以通过访问器本地化 Moose 属性中的哈希引用吗?

c - 将哈希键(无符号长整型)安全地转换为 int

csv - 使用 Serde 将结构实例写入文件时如何向结构实例添加额外的数据点?

excel - 如何在一个单元格中获取一大段文本并插入回车以将其分解为多个单元格?

iphone - Objective-C : Fowler–Noll–Vo (FNV) Hash implementation

arrays - Ruby,创建没有现有数组键值的数组

python - 使用 Pandas 计算导入的 csv 坐标之间的距离

perl - perl 如何在打印时识别变量的结尾?