0

如何在 perl 中合并多个 CSV 文件?

例如,我有文件 1 Packet1.csv看起来像:

#type, number, info, availability
computer, t.100, pentium 2, yes
computer, t.1000, pentium 3, yes
computer, t.2000, pentium 4, no
computer, t.3000, pentium 5, yes

和文件 2 Packet2.csv看起来像:

#type, number, info, availability
computer, t.100, pentium 2, yes
computer, t.1000, pentium 3, no
computer, t.2000, pentium 4, no
computer, t.4000, pentium 6, no

我想要的输出是单个文件,其中数据包的数量 不固定:

#type, number, info, **Packet1** availability, **Packet2** availability
computer, t.100, pentium 2, yes, yes
computer, t.1000, pentium 3, yes, no
computer, t.2000, pentium 4, no, no
computer, t.3000, pentium 5, yes
computer, t.4000, pentium 6, no
4

2 回答 2

3

回到您对多维散列的尝试:散列的散列 perl,您将需要更改正在使用的数据结构以存储特定元素的多个条目。

CSV 可以直观地读入具有 2 个级别的哈希。csv 的行可以通过它们的 ID 进行散列(在这种情况下,我猜 ID 是数字 't.100'、't.1000' 等),并且每行的值可以使用存储在二级散列中标题字符串作为其键。如果您使用 Data::Dumper 查看结构,它将看起来像这样:

$VAR1 = {
          't.1000' => {
                        'info' => 'pentium 3',
                        'availability' => 'yes',
                        'type' => 'computer'
                      },
          't.100' => {
                       'info' => 'pentium 2',
                       'availability' => 'yes',
                       'type' => 'computer'
                     }
        };

'number' 是否也是每个 'row hash' 的键取决于你,这取决于它的用处(通常你已经知道行的键才能访问它)。

这种数据结构可以很好地存储一个 CSV 文件。但是,我们需要增加一层额外的复杂性,以便以您描述的方式合并多个 CSV。例如,为了跟踪特定 ID 出现的文件,我们可以将第三个哈希存储为“可用性”键的值,因为该值在相同“数字”的条目之间发生变化:

'availability' => {
          'Packet1' => 'yes',
          'Packet2' => 'no'
        };

一旦所有文件都被读入这个结构,打印出最终的 CSV 就是一个循环外部哈希键的过程,并且对于每一行,以正确的顺序“连接”行的键。“数据包”哈希也可以循环检索所有“可用性”值,这些值可以附加到每行的末尾。

我希望这可以帮助您了解处理此类数据的一种可能方式。如果您发现它们很困难,您可以询问实施的特定部分,我会很乐意详细说明。

于 2012-11-28T13:49:15.717 回答
0
  • 您如何识别哪台计算机是哪台?您是否依赖前三个字段作为计算机标识?
  • 如果第一个字段不是computer怎么办?
  • 如果这两个文件与计算机类型不一致会怎样?

在弄清楚如何处理这个问题之前,你真的必须回答这些问题。但是,您可能必须处理引用

我认为您的问题与标准 Perl 数据结构仅存储单个值这一事实有关。您可以拥有单个值的哈希值,也可以拥有单个值的数组,但每个结构中不能有多个值。Perl 通过使用引用来解决这个问题。

例如,假设您有一个名为%computer的散列,它由第二个字段键入:

my %system;

$system{t.100} = {}    #This is a hash of hashes
$system{t.100}->{INFO} = "pentium 2";
$system{t.100}->{TYPE} = "computer";
$computer{t.100}->{AVAILABLITY} = []  #Storing an array in this hash entry (hash of hashes of arrays)
$computer{t.100}->{AVAILABILITY}->[0] = "yes";
$computer{5.100}->{AVAILABILITY}->[1] = "yes";

您还可以通过取消引用数组来使用push和:pop

push @{ $computer{t.100}->{AVAILABILITY} }, "yes";

请注意,我用 包围了对数组的引用$computer{t.100}->{AVAILABILITY}@{...}它从对数组的引用返回到数组。

我希望这是你要问的。您可以使用Text::CSV模块来解析您的 CSV 文件,但如果格式不太古怪,您可能只需使用该split命令。

于 2012-11-28T14:46:30.240 回答