Perl:比较两个字符串的两个文件

时间:2014-04-16 18:08:43

标签: string perl file compare

我有两个CSV文件。两者都有一个包含相同数据的列,区别在于一个文件在该列中包含的数据多于另一个文件。

我想打印出file2的行,其中包含该列中与其他文件中相同的字符串。

例如:

文件1

App_Int1     SID_bla1
App_Int2     SID_bla2
App_Int_4    SID_bla4

file2的

SID_bla1     hello     bye    ...
SID_bla2     good      bad    ...
SID_bla5     hey       ho     ....
SID_bla4     hi        cheers ...

我希望输出像这样

SID_bla1     hello     bye    ...
SID_bla2     good      bad    ...
SID_bla4     hi        cheers ...

由于file1不包含SID_bla5,因此不会打印SID_bla5行。

这是我的代码,但它不起作用,有人可以给我一些提示吗?

#!C:\Perl\bin\perl
use strict;
use warnings;

my $file = $ARGV[0] || die "Need to get CSV file on the command line\n";
my $mystring = "";

open(my $data, '<', $file) || die "Could not open '$file' $!\n";
my $newfile = "fooNew3.txt";
open(FILE2, ">", $newfile) || die "Could not open file";

my $file2 = "export.txt";
open(my $data2, '<', $file2) || die "Could not open '$file2' $!";

my $mystring2 = "";
my $line2;
my %filehash;
my @fields2 = "";

while ($line2 = <$data2>) {
  chomp $line2;

  @fields2 = split(";", $line2);
  while (my $line = <$data>) {
    chomp $line;

    my @fields = split(";", $line);
    if ($filehash{ $fields2[0] } eq $fields[1]) {
      # if the first column of file2 is identical with the second column of file1
      # then output the identical string and the second column of file2
      # which belongs to the first column of file2 (which is the identical string)

      print FILE2 join ';', "$fields[1]; $filehash{$fields2[0]} $fields2[1] \n";
    }

这会有什么问题?

  if ($fields2[0] eq $fields[1] {
    print $fields2[0] $fields2[1] $fields2[2];
  }

3 个答案:

答案 0 :(得分:1)

作为perl脚本,您的代码可以简化为以下内容:

#!C:\Perl\bin\perl
use strict;
use warnings;

die "Usage: $0 File1 File2\n" if @ARGV != 2;

my $file2 = pop;

my %seen;
while (<>) {
    my @F = split;
    $seen{$F[1]}++;
}

local @ARGV = $file2;
while (<>) {
    my @F = split;
    print if $seen{$F[0]};
}

答案 1 :(得分:0)

你过度设计了这个问题。

$ awk 'NR == FNR {a[$2]; next}$1 in a' file1.txt file2.txt
SID_bla1     hello     bye    ...
SID_bla2     good      bad    ...
SID_bla4     hi        cheers ...

如果您想使用Perl,请使用-ap调用它进行autosplit,并在每行上自动循环并打印。

如果您的数据为; - 已分开,例如

<强> FILE1.TXT

App_Int1;SID_bla1
App_Int2;SID_bla2
App_Int_4;SID_bla4

<强> FILE2.TXT

SID_bla1;hello;bye;...
SID_bla2;good;bad;...
SID_bla5;hey;ho;....
SID_bla4;hi;cheers;...

您可以将字段分隔符设置为;

$ awk -F';' 'NR == FNR {a[$2]; next}$1 in a' file1.txt file2.txt
SID_bla1;hello;bye;...
SID_bla2;good;bad;...
SID_bla4;hi;cheers;...

答案 2 :(得分:0)

虽然您没有很好地描述,但我想要的是file2中第一列匹配任何值的所有行在file1的第二列。这个简短的Perl程序将为您做到这一点。

我假设文件中的字段由空格 - 空格或制表符的任何混合分隔。它的工作原理是根据file1中的数据构建哈希值,该哈希值对于每个记录的第二列中出现的每个字符串都具有 true 值。这就是第一个文件所需的一切。

然后打开并处理file2。使用散列检查每行中的第一个字段,如果存在相应的散列元素,则打印该行。

use strict;
use warnings;
use autodie;

my $fh;
my %wanted;

open $fh, '<', 'file1.txt';
while (<$fh>) {
  my @fields = split;
  $wanted{$fields[1]} = 1;
}

open $fh, '<', 'file2.txt';
while (<$fh>) {
  my @fields = split;
  print if $wanted{$fields[0]};
}

<强>输出

SID_bla1     hello     bye    ...
SID_bla2     good      bad    ...
SID_bla4     hi        cheers ...