Perl处理CSV重复记录:仅告警值不同的重复项需求
修改Perl CSV重复检查代码:仅在汇率不同时触发警告
我帮你调整了代码,现在它只会在相同FROM/TO币种组合但汇率(RATE)不同的时候才抛出警告,汇率完全一致的重复记录会被直接忽略,同时依然只针对TO为USD的记录进行检查:
#!/usr/bin/perl use strict; use warnings; use Text::CSV; # 存储每个FROM-TO组合下已出现的汇率及对应行 # 结构: $data{FROM-TO}->{RATE} = [行数据列表] my %data; # 存储需要警告的冲突记录(同FROM-TO但不同RATE) my %dupes; my $csv = Text::CSV->new () or die "Cannot use CSV: ".Text::CSV->error_diag (); open my $fh, "<", 'D:\Longview\ENCDEVD740\DataServers\ENCDEVD740\lvaf\inbound\data\enc_meroll_fxrate_soa_load.csv' or die "Cannot open CSV: $!"; # 读取表头行并跳过 my $header = $csv->getline($fh); while ( my $row = $csv->getline( $fh ) ) { my ($from_curr, $to_curr, $rate) = @$row; # 只处理TO为USD的记录,其他直接跳过 next unless $to_curr eq 'USD'; my $key = join($;, $from_curr, $to_curr); if (exists $data{$key}) { # 检查当前汇率是否已经在该币种组合下出现过 if (exists $data{$key}->{$rate}) { # 汇率相同,直接跳过,不标记重复 push @{$data{$key}->{$rate}}, $row; } else { # 汇率不同,需要标记冲突 # 如果是第一次发现冲突,先把之前所有同组合的记录加入dupes unless (exists $dupes{$key}) { # 遍历该组合下所有已有的汇率对应的行 foreach my $existing_rate (keys %{$data{$key}}) { push @{$dupes{$key}}, @{$data{$key}->{$existing_rate}}; } } # 再把当前行加入冲突列表 push @{$dupes{$key}}, $row; # 把当前汇率和行也加入data,方便后续检查 $data{$key}->{$rate} = [$row]; } } else { # 该币种组合第一次出现,存入data $data{$key}->{$rate} = [$row]; } } $csv->eof or $csv->error_diag(); close $fh; # 输出冲突警告 if (%dupes) { warn "警告:发现同币种组合但汇率不同的记录(TO=USD):\n"; warn "-------------------------------------------------\n"; foreach my $key (keys %dupes) { my ($from, $to) = split($;, $key); print "币种组合: $from -> $to\n"; foreach my $conflicting_row (@{$dupes{$key}}) { print "\t记录: @$conflicting_row\n"; } print "\n"; } } else { print "未发现TO=USD且汇率冲突的重复记录\n"; }
关键修改说明:
- 数据结构调整:把
%data改成嵌套哈希,用来跟踪每个FROM-TO组合下所有出现过的汇率,避免误判相同汇率的重复记录 - 提前过滤:只处理TO为USD的记录,减少不必要的计算开销
- 冲突判断逻辑:只有当相同
FROM-TO组合出现不同汇率时,才将所有相关记录加入警告列表,相同汇率的重复行直接跳过 - 友好输出:优化了警告信息的格式,增加了无冲突时的提示
测试用CSV示例数据
FROMCURRENCY,TOCURRENCY,RATE AED,USD,0.272257011 ANG,USD,0.557584544 ARS,USD,0.01421147 AUD,USD,0.68635 AED,USD,0.272257011 ANG,USD,0.557584544 ARS,USD,0.01421147 AUD,USD,0.69000 # 这条会触发警告,因为和之前的0.68635不同
如果运行上面的测试数据,代码会只针对AUD->USD的两条不同汇率记录发出警告,其他相同汇率的重复行不会被标记。
内容的提问来源于stack exchange,提问作者Viky Maradia
相关产品推荐
相关产品推荐

