Arrays 使用Perl比较两个CSV文件

Arrays 使用Perl比较两个CSV文件,arrays,perl,csv,hash,compare,Arrays,Perl,Csv,Hash,Compare,我有两个CSV文件要与Perl进行比较 我有代码使用Perl将文件导入,它为我提供了一个文件的哈希引用数组 使用将正确显示我的所有数据导入 use strict; use warnings; use Text::CSV::Slurp; use Data::Dumper::Concise; my $file1_src = "IPB-CSV.csv"; my $file2_src = "SRM-CSV.csv"; my $IPB = Text::CSV::Slurp->load(fil

我有两个CSV文件要与Perl进行比较

我有代码使用Perl将文件导入,它为我提供了一个文件的哈希引用数组

使用将正确显示我的所有数据导入

use strict;
use warnings;

use Text::CSV::Slurp;
use Data::Dumper::Concise;

my $file1_src = "IPB-CSV.csv";

my $file2_src = "SRM-CSV.csv";

my $IPB = Text::CSV::Slurp->load(file => $file1_src);
my $SRM = Text::CSV::Slurp->load(file => $file2_src);

print Dumper($IPB);
print Dumper($SRM);
转储的结果如下所示

$IPB

[
  {
    Drawing => "1001"
  },
  {
    Drawing => "1002"
  },
  {
    Drawing => "1003"
  }
]
$SRM

[
  {
    Drawing => "1001",
    Figure => "Figure 2-8",
    Index => 2,
    Nomenclature => "Some Part"
  },
  {
    Drawing => "1002",
    Figure => "Figure 2-8",
    Index => 2,
    Nomenclature => "Some Part"
  },
  {
    Drawing => "2001",
    Figure => "Figure 2-8",
    Index => 2,
    Nomenclature => "Some Part"
  },
  {
    Drawing => "2002",
    Figure => "Figure 2-8",
    Index => 2,
    Nomenclature => "Some Part"
  }
]
我想根据每个散列的
绘图
键比较两个数组,并创建两个CSV文件,如下所示

  • 包含
    $IPB
    中的项目,但不包含
    $SRM
    ,仅包含“绘图”列中的数据

  • 项目位于
    $SRM
    但不在
    $IPB
    中的另一个字段,其中包含与
    绘图
    列相关的所有字段


我找到了很多信息来比较文件是否匹配,或者比较单个数据段的哈希或数组,但是我找不到特定于我需要的东西。

既然绘图是排序的标准,为什么不“索引”呢如果绘图索引是键,相应的数据是一个对应的值,那么将数据转换为更方便的内容

my %ipb;
for my $record ( @$IPB ) {
    my $index = $record->{Drawing};
    push @{ $ipb{$index} }, $record;
}

my %srm;
for my $record ( @$SRM ) {
    my $index = $record->{Drawing};
    push @{ $srm{$index} }, $record;
}
现在,找出
$IPB
$SRM
所特有的索引应该是轻而易举的事了:

use List::MoreUtils 'uniq';
my @unique_ipb = uniq( grep { $ipb{$_} and not $srm{$_} } keys( %ipb ), keys( %srm ) );
my @unique_srm = uniq( grep { $srm{$_} and not $ipb{$_} } keys( %ipb ), keys( %srm ) );
两者的共同点是什么

my @intersect = uniq( grep { $srm{$_} and $ipb{$_} } keys( %ipb ), keys( %srm ) );
图纸索引1002的所有图号是多少

print $_->{Figure}, "\n" for @{ $ipb{1002} // [] }, @{ $srm{1002} // [] };

这有点复杂,因为您的数据结构不太适合进行比较。您有对哈希引用数组的引用,并且您关心hashref的一个键中的数据。我的第一步是将IPB展平为一个数组(因为在这个数组下没有数据),并将SRM转换为单个hashref

my @ipbarray = map { ${$_}{Drawing} } $IPB; # Creates an array from IPB.
my $srmhash = {};
for my $hash ($SRM) {
  ${$srmhash}{${$hash}{Drawing}} = $hash unless defined ${$srmhash}{${$hash}{Drawing}}; # Don't overwrite if it exists
}
现在,我们又有了两个可用的数据结构

下一步是对比这些值:

my @ipbonly = ();
my @srmonly = ();

for my $ipbitem (@ipbarray) {
  push @ipbonly, ( Drawing => $ipbitem } unless defined ${$srmhash}{$ipbtem};
}

for my $srmitem (keys $srmhash) {
  push @srmonly, ${$srmhash}{$srmitem} unless grep { $_ == $srmitem } @ipbarray;
}

此时,@ipbonly和@srmonly将包含您想要的数据。

此简短程序使用您的示例值作为
$ipb
$srm
,并创建我认为您想要的输出。(请不要将大写字母用于除包名等全局标识符以外的任何内容。)

有几个问题

  • 如果不进行进一步的索引,使用该函数将为您留下两个哈希数组,这些哈希数组对该任务没有任何用处。通过逐行处理文件,从零开始创建适当的数据结构会更好


  • 您说您的第二个文件必须包含与每个
    绘图
    键相关的所有信息,但是,由于Perl哈希本身是无序的,
    Text::CSV::Slurp
    丢失了字段名的顺序。最好的方法是按找到的顺序打印数据,但在数据前面有一行显示字段名的标题行。这是避免使用
    Text::CSV::Slurp

输出

file1.csv

1003
Drawing,Nomenclature,Index,Figure
2001,Some Part,2,Figure 2-8
2002,Some Part,2,Figure 2-8
file2.csv

1003
Drawing,Nomenclature,Index,Figure
2001,Some Part,2,Figure 2-8
2002,Some Part,2,Figure 2-8

在IPB中的每个元素上循环,捕获图纸值,检查SRM中是否存在该值,等等。。。在您尝试了一些编码但仍然存在问题后,发布代码并提出问题。好运
Text::CSV::Slurp
是一把巨大的锤子,它会让您的数据结构不适合您的任务。请您显示两个CSV数据文件好吗?我会使用和SQL联接。我认为我的$hash(@$SRM)的
需要是我的$hash(@$SRM)在这里-或者,为了与和一致,类似于我的$hash(@{$SRM})的
。我相信更高版本的perl只需在arrayref上迭代,而无需显式引用。但是,是的,这两种方法都会起作用,并且可能更向后兼容。谢谢!这很有效。这只会在我的个人系统上用于标记任何一组数据中缺少的数据,以便我们可以返回并查看是否缺少所需的数据,或者缺少可以忽略的数据。如果字段(列)的顺序与它们的输入方式不符,我可以。如果有必要,我可以在excel中随时移动它们。我之所以使用Text::CSV::Slurp,是因为它在另一个示例中,而不是因为任何特殊原因我想保留它。这是我6年多来的第一个perl脚本。我以前更熟悉,但现在看来,如果你不使用它,我想你会失去它。再次感谢您的帮助。Perl在六年中发生了很大的变化!如果你展示你的数据,我会写一些东西,逐行处理,帮助你回到itSo。今天我去实际使用脚本,我突然遇到了问题。自从我最初发布这篇文章以来,我已经重新格式化了我的电脑。安装和设置perl与以前一样。然而,现在即使我运行上面的代码来尝试和测试东西,我的file2.csv还是出了问题。而且不仅仅是像以前那样(字段被混淆)无序,而是整个列都无序。所以我所有的数据都很混乱,甚至很难在excel中开始排序。知道为什么我身上突然发生了变化吗?@SaskiFX:file1.csv和file2.csv的内容都是按图纸编号排序的。我猜你以前没有注意到,因为记录太少了。你想要什么样的顺序?