我希望能够将此CSV文件读入数组或散列数组以进行操作。我怎么能去做呢?
例如,我的文件包含以下内容(第一行是标题):
Name,Age,Items,Available
John,29,laptop,mouse,Yes
Jane,28,desktop,keyboard,mouse,yes
Doe,56,tablet,keyboard,trackpad,touchpen,Yes
第一列是名称,第二列是年龄,第三列是项目,但项目可以包含多个以逗号分隔的内容,最后一列是人员可用性。
我怎样才能准确地读到这个?
答案 0 :(得分:5)
格式正确的CSV引用包含逗号作为值的一部分的字段。如果您的CSV格式正确,请使用Text::CSV
模块:
use Text::CSV;
my $csv = Text::CSV->new();
while (my $row = $csv->getline(\*DATA)) {
my $name = $row->[0];
my $age = $row->[1];
my @items = split /,/, $row->[2];
my $available = $row->[3];
print "$name/$age/@items/$available\n";
}
__DATA__
Name,Age,Items,Available
John,29,"laptop,mouse",Yes
Jane,28,"desktop,keyboard,mouse",yes
Doe,56,"tablet,keyboard,trackpad",touchpen,Yes
输出:
Name/Age/Items/Available
John/29/laptop mouse/Yes
Jane/28/desktop keyboard mouse/yes
Doe/56/tablet keyboard trackpad touchpen/Yes
如果您的CSV格式不正确,您需要根据您的数据知识实施自定义解析。假设Items列是唯一的多值字段,您可以在逗号上拆分,然后删除具有已知位置的字段。无论剩下什么都是物品。
while (my $line = <DATA>) {
chomp $line;
my @record = split /,/, $line;
my $name = shift @record;
my $age = shift @record;
my $available = pop @record;
my @items = @record;
print "$name/$age/@items/$available\n";
}
__DATA__
Name,Age,Items,Available
John,29,laptop,mouse,Yes
Jane,28,desktop,keyboard,mouse,yes
Doe,56,tablet,keyboard,trackpad,touchpen,Yes
或者,您可以使用数组切片来获得相同的结果:
my ($name, $age, $available, @items) = @record[0, 1, -1, 2 .. @record - 2];
答案 1 :(得分:2)
由于您的数据实际上是格式正确的CSV文件,因此您可以使用标准工具来读取和存储它
Name,Age,Items,Available
John,29,"laptop,mouse",Yes
Jane,28,"desktop,keyboard,mouse",yes
Doe,56,"tablet,keyboard,trackpad,touch pen",Yes
与我原来的答案一样,此代码使用Text::CSV
来解析每行输入。但不必重新格式化,每行可以直接推到数组@data
与以前一样,它符合STDIN的阅读标准。但这次我使用Data::Dump
来揭示已构建的内存数据结构。如果在命令行上运行它,则应使用
$ perl unpack_csv.pl text.csv
use strict;
use warnings 'all';
use Text::CSV;
my $csv = Text::CSV->new;
my @data;
while ( <> ) {
$csv->parse($_);
my @row = $csv->fields;
push @data, \@row;
}
use Data::Dump;
dd \@data;
答案 2 :(得分:0)
我现在意识到OP的文件可能包含格式正确的CSV数据,这使得这个答案变得多余
然而,问题并没有改变以显示真实数据,所以我在这里留下这个答案,以防问题的主题和内容引诱人们有一个问题 解决
我建议您使用中间程序正确格式化CSV文件。获得标准格式文件后,可以使用带有Text::CSV
,Excel或类似内容的Perl处理生成的输出
此程序使用Text::CSV
读取您的输入数据,并在必要时编写引号括起来的Items
列
它的工作原理是使用Text::CSV->parse
将每一行拆分为字段,然后为新字段1,2和4保留前两个和最后一个字段。剩下的是用逗号,
连接的并用于字段3.四个结果值将传递回Text::CSV->combine
并打印
它符合从STDIN读取和写入STDOUT的标准,所以如果你在命令行上运行它应该使用
$ perl reformat_csv.pl text.csv > new_text.csv
use strict;
use warnings 'all';
use Text::CSV;
my $csv = Text::CSV->new;
while ( <> ) {
$csv->parse($_);
my @row = $csv->fields;
my $f1 = shift @row;
my $f2 = shift @row;
my $f4 = pop @row;
my $f3 = join ',', @row;
$csv->combine($f1, $f2, $f3, $f4);
print $csv->string, "\n";
}
Name,Age,Items,Available
John,29,"laptop,mouse",Yes
Jane,28,"desktop,keyboard,mouse",yes
Doe,56,"tablet,keyboard,trackpad,touchpen",Yes