【问题标题】:String comparison字符串比较
【发布时间】:2016-03-16 19:16:16
【问题描述】:

我有两个从 IntexCalc 和 Intex API 生成的文件,我想比较它们的内容。我不想逐行比较。下面的示例将提供更多详细信息。

文件 1

LOSS_UNITS[\"GRPY\"]==CDR  
LOSS_USERCURVE_TYPE[\"GRPY\"]==PCT_MULTIPLY  
LOSS_USERCURVE_INDEX_OFFSET[\"GRPY\"]==BY_LOAN_AGE  
LOSS_RATE[\"GRPY\"]==100  
LOSS_NONPERF_ADV_PCT_P[\"GRPY\"]==0  
LOSS_NONPERF_ADV_PCT_I[\"GRPY\"]==0  
SEVERITY_USERCURVE_TYPE[\"GRPY\"]==NONE  

文件 2

LOSS_USERCURVE_TYPE[\"GRPY\"]=PCT_MULTIPLY  
LOSS_NONPERF_ADV_PCT_P[\"GRPY\"]=0  
LOSS_UNITS[\"GRPY\"]=CDR  
LOSS_NONPERF_ADV_PCT_I[\"GRPY\"]=0  
SEVERITY_USERCURVE_TYPE[\"GRPY\"]=NONE  
LOSS_SEVERITY[\"GRPY\"]=31.73  
LOSS_USERCURVE_INDEX_OFFSET[\"GRPY\"]=BY_DEAL_AGE  
  1. 我想比较两个文件中的LOSS_UNITS[\"GRPY\"] 标志值。在这两个文件中,无论它们在文件中的位置如何,它们在 =/== 之后的值都是相同的,因此这个标志值是相等的。

  2. 文件1中LOSS_USERCURVE_INDEX_OFFSET[\"GRPY\"]的标志值为BY_LOAN_AGE,文件2中为BY_DEAL_AGE,所以这个标志值不同。

  3. 标志 LOSS_RATE[\"GRPY\"] 仅存在于文件 1 中,所以这是一个区别

  4. 标志 LOSS_SEVERITY[\"GRPY\"] 仅存在于文件 2 中,因此这也是一个区别。

比较这种文件结构的最佳方法或工具是什么?

【问题讨论】:

  • diff -u0 <(sort file1) <(sort file2)comm -3 <(sort file1) <(sort file2)
  • @ysth 这两个命令都很可爱,但是你需要挤一些 sed 过滤器来消除由“=”和“==”引起的差异。而且报告并不完美。

标签: string perl compare string-comparison


【解决方案1】:

我建议你使用Data::Diff 模块

它返回对包含参数之间差异摘要的哈希的引用。关键是

  • same — 两种情况下相同的元素
  • diff — 给定键具有不同值的元素
  • uniq_auniq_b — 仅出现在一种或另一种结构中的元素


use strict;
use warnings 'all';
use autodie;

use Data::Dump;
use Data::Diff 'Diff';

my %f1 = do {
    open my $fh, '<', 'file1.txt';
    map { s/\s+\z//; split /=+/, $_, 2 } <$fh>;
};

my %f2 = do {
    open my $fh, '<', 'file2.txt';
    map { s/\s+\z//; split /=+/, $_, 2 } <$fh>;
};

my $diff = Diff(\(%f1, %f2));
dd $diff;

输出

{
  diff   => {
              "LOSS_USERCURVE_INDEX_OFFSET[\\\"GRPY\\\"]" => { diff_a => "BY_LOAN_AGE", diff_b => "BY_DEAL_AGE", type => "" },
            },
  same   => {
              "LOSS_NONPERF_ADV_PCT_I[\\\"GRPY\\\"]"  => { same => 0, type => "" },
              "LOSS_NONPERF_ADV_PCT_P[\\\"GRPY\\\"]"  => { same => 0, type => "" },
              "LOSS_UNITS[\\\"GRPY\\\"]"              => { same => "CDR", type => "" },
              "LOSS_USERCURVE_TYPE[\\\"GRPY\\\"]"     => { same => "PCT_MULTIPLY", type => "" },
              "SEVERITY_USERCURVE_TYPE[\\\"GRPY\\\"]" => { same => "NONE", type => "" },
            },
  type   => "HASH",
  uniq_a => { "LOSS_RATE[\\\"GRPY\\\"]" => 100 },
  uniq_b => { "LOSS_SEVERITY[\\\"GRPY\\\"]" => 31.73 },
}

【讨论】:

    【解决方案2】:

    一个没有灵感的解决方案:将键和值放入两个哈希中并进行比较。

    sub f2h {
      my( $hr, $path ) = @_;    
      open FILE, $path or die "$path: couldn't open: $!";
      while( my $line = <FILE> ){
        $line =~ s/\s+$//;   # there are trailing spaces in your data
        my( $key, $val ) = split( /==?/, $line );
        $hr->{$key} = $val;
      }
      close FILE;
    }
    
    my %h1;
    my %h2;
    f2h( \%h1, "file1.dat" );
    f2h( \%h2, "file2.dat" );
    while( my( $k, $v ) = each %h1 ){
      if( exists( $h2{$k} ) ){
        print "different $k\n" if $h2{$k} ne $v;
      } else {
        print "$k missing in 2\n";
      }
    }
    while( my( $k, $v ) = each %h2 ){
      print "$k missing in 1\n" unless exists $h1{$k};
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-06
      相关资源
      最近更新 更多