【问题标题】:Perl - Comparison of Files using specific substringsPerl - 使用特定子字符串比较文件
【发布时间】:2016-06-16 10:29:36
【问题描述】:

我编写了 thsi 脚本来比较两个文件的行,并将公共/非公共行输出到两个不同的文件中。脚本是:

use strict;
use warnings;
use autodie;

my $f1 = shift || "CSP8216.TXT";                                            
my $f2 = shift || "CSP8217.TXT";                                            

open my $fh1, '>', 'file1';
open FH2, '>', 'file2';

my %results;

open my $file1, '<', $f1;                                                   
while (my $line = <$file1>) { 
$results{$line} = 1  
}                           

open my $file2, '<', $f2;                                                   
while (my $line = <$file2>) {
   $results{$line}++ 
}                           

foreach my $line (sort { $results{$b} <=> $results{$a} } keys %results) 
{   
    if ($results{$line} >= 1)
    {
    print {$fh1} "$line";
    }
   else 
   {
   print FH2 "$line";
   }
}

我的问题是当我尝试修改此脚本但根据每行的特定子字符串运行比较时,即:

  • 如果文件A的某一行的特定子串与文件B中另一行的特定子串匹配,则将文件B的/整个/行输出到fh1,否则输出到fh2。

我试过这个,但它不起作用 - 对 Perl 来说还是很新,任何帮助将不胜感激:

use strict;
use warnings;
use autodie;

my $f1 = shift || "CSP8216.TXT";                                            
my $f2 = shift || "CSP8216.TXT";                                            

open my $fh1, '>', 'file1';
open FH2, '>', 'file2';

my %results;

open my $file1, '<', $f1;                                                   
while (my $line = <$file1>) 
{
    my $sbs1 = substr($line, 0, 10); 
    $results{$sbs1} = 1 
}                           

open my $file2, '<', $f2;                                                   
while (my $line = <$file2>) 
{
    my $sbs2 = substr($line, 0, 10);
    $results{$sbs2}++ 
}                           

foreach my $line (sort { $results{$b} <=> $results{$a} } keys %results) 
{   
    if ($results{$line} >= 1)
    {
    print {$fh1} "$line";
    }
    else 
    {
    print FH2 "$line";
    }
}

这不起作用,我感觉它的逻辑有问题,它只在一行中输出子字符串。

【问题讨论】:

  • 如果相同的内容在文件 A 或文件 B 中出现两次,则您的代码无法按预期工作。解决方案是为每个文件使用单独的哈希,然后检查两个哈希中是否存在一行。
  • $results{$line} &gt;= 1 应该是$results{$line} &gt; 1,否则(根据代码)两个文件中的所有行都相同。

标签: perl file compare substring


【解决方案1】:

根据我的评论,如果我们需要支持单行可以在一个文件中出现两次,我们需要将文件 A 和文件 B 中的行分开。

开启选项就是解决这样的基本问题

open my $fh1, '<', $filename1 or die "Can't open $file1: $!";
while (my $line = <$fh1>) {
    $combined{$line} = $file1{$line} = 1;
}

open my $fh2, '<', $filename2 or die "Can't open $file2: $!";
while (my $line = <$fh2>) {
    $combined{$line} = $file2{$line} = 1;
}

open my $out1, '>', $outfilename1 or die "...";
open my $out2, '>', $outfilename2 or die "...";

for my $line (keys %combined) {
    if ($file1{$line} && $file2{$line}) {
        print $out1 $line;
    } else {
        print $out2 $line;
    }
}

为了解决子字符串问题,我会将每个文件中的子字符串保留为哈希中的键。但是,我不只是存储真实值,而是将完整的字符串作为值存储在 %file2 中:

open my $fh1, '<', $filename1 or die "Can't open $file1: $!";
while (my $line = <$fh1>) {
    my $substr = substr($line, 0, 10);
    $combined{$line} = $file1{$substr} = 1;
}

open my $fh2, '<', $filename2 or die "Can't open $file2: $!";
while (my $line = <$fh2>) {
    my $substr = substr($line, 20, 30);
    $combined{$line} = 1;
    $file2{$substr} = $line;
}

open my $out1, '>', $outfilename1 or die "...";
open my $out2, '>', $outfilename2 or die "...";

for my $line (keys %combined) {
    my $substr1 = substr($line, 0, 10);
    my $substr2 = substr($line, 20, 30);
    if ($file1{$substr1} && $file2{$substr2}) {
        print $out1 $file2{$substr2};
    } else {
        print $out2 $line;
    }
}

【讨论】:

  • 我尝试了不同版本的代码,我可以编辑我原来的帖子还是尝试一个新的?
【解决方案2】:

这对我有用

#!/usr/bin/perl

use warnings;
use autodie;

my %results;

my $f1 = shift || "CSP8216.TXT";
my $f2 = shift || "CSP8217.TXT";

open my $fh1, '>', 'file1';
open my $fh2, '>', 'file2';


open my $file1, '<', $f1;
while (my $line = <$file1>) {
    my $sbs1 = substr($line, 0, 10);
    $results{$sbs1} = 1
}

open my $file2, '<', $f2;
while (my $line = <$file2>) {
    my $sbs2 = substr($line, 0, 10);
    if (!$results{$sbs2}) {
        $results{$sbs2} = 1;
    }
    $results{$sbs2}++
}

foreach my $line (sort { $results{$b} <=> $results{$a} } keys %results) {
    if ($results{$line} > 1) {
        print {$fh1} "$line";
    }
    else {
        print {$fh2} "$line";
    }
}

【讨论】:

    猜你喜欢
    • 2016-06-15
    • 2015-03-14
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    相关资源
    最近更新 更多