从 Perl 的哈希表写入到 CSV 文件

9
我有一个目前从 FILE 1 中读取内容并匹配特定字符的程序,例如下面的样子:
Type, Fruit, Description, quantity
tropical, banana, tasty and yummy, 5
tropical, grapefruit, bitter and not yummy, 2
...以此类推
首先,我想为每个“Type”、“Fruit”、“Description”和“Quantity”创建哈希表,并将不同的值存储在参考哈希表中。使用下面的代码可以很好地实现这一点。
use strict;
use warnings;
use Data::Dumper;
use Text::CSV;

my %MacroA = ('Type' => {}, 'Fruit' => {}, 'Description' => {}, 'Quantity' =>  {});         

open (my $file, '<', 'FRUITIES.txt') or die $!;     

while (my $line = <$file>)                                                             {                                        

if ($line =~ /\b(tropical)\b,/) {                                   
$MacroA{Type}->{$1}++;
}

if ($line =~ /,\b(banana|grapefruit)\b,/) {                             
$MacroA{Fruit}->{$1}++;
}

if ($line =~ /,([\w\s]+?),/) {                                  
$MacroA{Description}->{$1}++;
}

if ($line =~ /,([\d]+?)/) {                             
$MacroA{Quantity}->{$1}++;
}
        }

close $file;                    

我的问题是如何将这些数据(数据不固定)放入CSV文件或任何相关的文件(可能是XLS),使其成为一个带有每个哈希散列列的表格(“类型”,“水果”,“描述”,“数量”)。


3
你试过运行你的代码吗?它有编译错误。你应该先修复这些错误,然后看看 Text::CSV(你似乎已经找到了它)。 - simbabque
嗨@simbabque,是的,这不是原始代码,只是一个例子。我看了一下Text::CSV,但我不确定如何使用它。 - El_Commandantee
@El_Commandantee 如果这只是你自己使用的话,或者你可以写“脏”代码,不需要模块和其他东西,那么你可以很容易地使用 Perl 核心函数编写代码。 - gaussblurinc
1
你的原始数据是伪CSV格式,但你将这些数据处理成不同单词计数的哈希表。像这样的数据并不是以表格形式存在的,因此无法真正表示为CSV。也许你应该展示一下你所期望的样本数据结果。顺便问一句,葡萄柚有什么问题吗?! - Borodin
很抱歉,我不明白哈希的意义。您的数据已经是CSV格式了。如果您将其原样导入Google文档中,它将以您要求的格式显示。 - Borodin
显示剩余4条评论
2个回答

3

我认为哈希的哈希是一个好东西,但我觉得你没有以一种容易检索的方式存储它。

有一种方法可以这样做。

{ id_1 => {
             data_1 => "blah",
             data_2 => "foo",
             ...
           },
  id_2 => {
             ...
           },
  ...
 }

首先,您需要选择哪一列将成为“ID”。这将确定每个行的唯一性。假设您的例子中选择水果,因为我们假设同一文件中不会出现两个水果。所以我们会得到如下内容:

{ banana => {
             type => "tropical",
             description => "tasty and yummy",
             ...
           },
  grapefruit => {
             ...
           },
  ...
 }

为了将其改回CSV格式,我们通过哈希表进行循环遍历。
my %fruit_data; #let's assume that this already has the data in it

foreach my $fruit ( keys %fruit_data ) { 

    #given the $fruit you can now access all the data you need
    my $type = %fruit_data{$fruit}{'type'};
    my $desc = %fruit_data{$fruit}{'description'};
    # etc...

    # then you may want to store them in a scalar in any order you want
    my $row = "$field,$type,$desc etc.\n";

    # then work your way from there

}

2

如果你需要编写Excel文件,可以使用Spreadsheet::WriteExcel

关于CSV文件-原始的CSV文件使用","作为分隔符和"\n"作为字符串分隔符。如果你想将一些哈希引用数组写入CSV文件,最好自己编写一个简单的子程序,类似于这个:

use strict;
use warnings;

sub write_csv {

  my ($array_ref, $fh) = @_;

  for my $row (@$array_ref) {
    print $fh join(',', map { $_, $row->{$_} } sort keys %$row), "\n";
  }
}

my $test = [
  {a => 1, ab => 2, type => '234k', count => '123'}, 
  {a => 3, ab => 2, type => 'some_type', count => 34},
];

open my $fh, '>', 'test.csv' or die $!;

write_csv($test, $fh);

3
当然,这在任何包含分隔符的单元格上都失败了。 - ugexe
2
我认为点赞一定是来自那些对这段代码的晦涩难懂感到印象深刻的人。它肯定不能回答问题。 - Borodin
谢谢你的好评,伙计。它至少回答了问题的一部分——如何使用Perl编写Excel文件以及如何编写CSV文件——因此如果您可以调整代码,它为正确答案提供了一般方向。根据要求编写自定义CSV文件更像是一个自由职业工作,而不仅仅是一个问题。 - moonsly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接