使用Perl我想比较两个文件,如何保留第一个文件中的唯一行,从第二个文件中丢弃匹配和重复的条目?

时间:2013-02-18 07:54:00

标签: perl

我有两个文件。

例如,文件#1的内容是:

dynSamp/dgenExp
dynSamp/dgenLod
dynSamp/dgenStm
dynSamp/dgenUpd
dynSamp/dmlnodExp
dynSamp/dmlnodLod
dynSamp/dmlnodStm
dynSamp/dmlnodUpd
dynSamp/dmndynLod
dynSam/dmndynStm
dynSamp/dmndynUpd
sample/genExp
sample/genLod
sample/genStm
sample/genUpd
sample/mlnodExp
sample/mlnodLod
sample/mlnodStm
sample/mlnodUpd
sample/mndynLod
sample/mndynStm
sample/mndynUpd
sample/genLod
dynSamp/dgenLod
dynSamp/dmlnodLod
dynSamp/dmndynLod
sample/mndynLod
sample/mlnodLod

文件#2的内容是:

dynSamp/dgenExp
dynSamp/dgenLod
dynSamp/dgenStm
dynSamp/dgenUpd
dynSamp/dmlnodStm
dynSamp/dmndynStm
dynSamp/dthrdsUpd_unix
dynSamp/dthrdsUpd_win
sample/genExp
sample/genLod
sample/genStm
sample/genUpd
sample/mlnodStm
sample/mndynStm
sample/thrdsUpd_unix
sample/thrdsUpd_win
sample/genLod
dynSamp/dgenLod
dynSamp/dmndynStm
dynSamp/dthrdsUpd_win

我想整理这两个文件。结果应该是第一个文件的唯一内容减去第二个文件的唯一/重复内容。

以下内容应该是文件#:

的剩余部分
dynSamp/dmlnodExp
dynSamp/dmlnodLod
dynSamp/dmlnodUpd
dynSamp/dmndynLod
dynSamp/dmndynUpd
sample/mlnodExp
sample/mlnodLod
sample/mlnodUpd
sample/mndynLod
sample/mndynUpd

任何人都可以帮我整理一下吗?谢谢!

3 个答案:

答案 0 :(得分:3)

你没有问任何问题,所以我认为你在提出算法时遇到了问题。这是一个:

  1. 打开第二个文件。
  2. 对于第二个文件中的每一行,
    1. 在由该行键入的哈希中创建一个元素。
  3. 打开第一个文件。
  4. 对于第一个文件中的每一行,
    1. 如果哈希没有该行键入的元素,
      1. 在由该行键入的哈希中创建一个元素。
      2. 打印该行。
  5. 此算法保留第一个文件的记录顺序。


    由于编码它是相当简单的,我也可以提供它。

    my %skip;
    {
       open(my $fh, '<', $ARGV[1])
          or die("Can't open \"$ARGV[1]\": $!\n");
       while (<$fh>) {
          chomp;
          ++$skip{$_};
       }
    }
    
    {
       open(my $fh, '<', $ARGV[0])
          or die("Can't open \"$ARGV[0]\": $!\n");
       while (<$fh>) {
          chomp;
          print "$_\n" if !$skip{$_}++;
       }
    }
    

    用法:

    script file1 file2 >file.out
    

    或排序:

    script file1 file2 | sort >file.out
    

答案 1 :(得分:0)

我想你想要这样的东西......

dogface@computer ~
$ cat sortit.pl
#!/usr/bin/perl -w
use strict;


my $file1 = 'file1';
my $file2 = 'file2';

my %bad;
my %good;

open BAD, "<$file2";
while (<BAD>) {
        chomp;
        $bad{$_} = 1;
}
close BAD;

open GOOD, "<file1";
while( <GOOD> ) {
        chomp;
        next if $bad{$_};
        $good{$_} = 1;
}
close GOOD;

open OUT, ">file3";
foreach my $key ( keys %good ) {
        print OUT $key . "\n";
}
close OUT;

dogface@computer ~
$ cat file1
dynSamp/dgenExp
dynSamp/dgenLod
dynSamp/dgenStm
dynSamp/dgenUpd
dynSamp/dmlnodExp
dynSamp/dmlnodLod
dynSamp/dmlnodStm
dynSamp/dmlnodUpd
dynSamp/dmndynLod
dynSam/dmndynStm
dynSamp/dmndynUpd
sample/genExp
sample/genLod
sample/genStm
sample/genUpd
sample/mlnodExp
sample/mlnodLod
sample/mlnodStm
sample/mlnodUpd
sample/mndynLod
sample/mndynStm
sample/mndynUpd
sample/genLod
dynSamp/dgenLod
dynSamp/dmlnodLod
dynSamp/dmndynLod
sample/mndynLod
sample/mlnodLod

dogface@computer ~
$ cat file2
dynSamp/dgenExp
dynSamp/dgenLod
dynSamp/dgenStm
dynSamp/dgenUpd
dynSamp/dmlnodStm
dynSamp/dmndynStm
dynSamp/dthrdsUpd_unix
dynSamp/dthrdsUpd_win
sample/genExp
sample/genLod
sample/genStm
sample/genUpd
sample/mlnodStm
sample/mndynStm
sample/thrdsUpd_unix
sample/thrdsUpd_win
sample/genLod
dynSamp/dgenLod
dynSamp/dmndynStm
dynSamp/dthrdsUpd_win

dogface@computer ~
$ ./sortit.pl

dogface@computer ~
$ cat file3
sample/mndynLod
dynSamp/dmlnodUpd
dynSamp/dmlnodLod
dynSamp/dmlnodExp
sample/mndynUpd
sample/mlnodUpd
sample/mlnodLod
dynSamp/dmndynLod
dynSamp/dmndynUpd
sample/mlnodExp
dynSam/dmndynStm

dogface@computer ~
$

哦,如果你想要对file3进行排序,请使用以下代码:

foreach my $key ( sort keys %good ) {
        print OUT $key . "\n";
}

答案 2 :(得分:0)

它在awk中有点直接排序:

awk 'FNR==NR{a[$0];next}{if(!($0 in a))print $0}' temp2 temp | sort -u

我认为dynSam/dmndynStm,也应根据您的要求包含在您的输出中。

> awk 'FNR==NR{a[$0];next}{if(!($0 in a))print $0}' temp2 temp | sort -u
dynSam/dmndynStm,
dynSamp/dmlnodExp,
dynSamp/dmlnodLod,
dynSamp/dmlnodUpd,
dynSamp/dmndynLod,
dynSamp/dmndynUpd,
sample/mlnodExp,
sample/mlnodLod,
sample/mlnodUpd,
sample/mndynLod,
sample/mndynUpd,
>