比较文件并将类似数据存储到不同的文件中

时间:2012-08-13 03:36:51

标签: regex string perl

**LIST.txt**
lambo
audi
bmw
merc
ferrari

LIST是包含汽车名称的文件,DETAILS是具有LIST.txt中命名的汽车详情的文件

**DETAILS.txt**
lambo_1 gallardo lp570
lambo_2 aventador lp700
lambo_3 reventon lp640
audi_1 R8 V10
audi_2 A8 diesel 
bmw_1 Z4 blue
bmw_2 M3 red
bmw_3 328i black
merc_1 slr mclaran
merc_2 sls wings

我想将每辆车的细节分成不同的文件,即我想在这种情况下使用lambo,audi,bmw和merc详细信息的4个文件,如file_1.txt,file_2.txt,file_3.txt和file_4。 TXT

file_1.txt
 lambo_1 gallardo lp570
    lambo_2 aventador lp700
    lambo_3 reventon lp640

类似其他文件

我是perl的新手,我想要你的帮助..我尝试通过搜索每个元素并将其存储到一个文件(计数器来更改文件名)来做到这一点,但我没有得到预期的结果。所以任何人都可以帮助我。

  use strict;
  use warnings;    
  my $counter;    
  open  my $fh, "<", "F1.txt" or die $!;  
  open  my $fh1, "<", "F2.txt" or die $!;    
  my @b = <$fh>;  my @a = <$fh1>;
  for (@b)  
  {        
    my $line1 = $_;         
    for (@a)        
    {              
      $line2 = $_;              
      if ($line1 =~ /^$line2$/)              
      {        
        $counter++;                    
        open my $outfile, ">>", "A_${counter}.txt";                    
        print $outfile $line2;                    
        close $outfile;              
      }   
    } 
  }

我正在尝试做这样的事情,但它并没有按要求为我提供正确的答案

3 个答案:

答案 0 :(得分:2)

这是多路复用的基本练习。我们甚至在Intermediate Perl中有一个例子(印刷版今天上架)。

您可以打开一堆写文件句柄,每种车型一个,将它们存储在哈希中,然后在遇到它时查找所需的文件句柄。这样做的好处是可以扫描一次细节,不像其他扫描多次的答案(以及将整个内容读入内存)。

第一部分使用map根据 list.txt 中的汽车创建输出文件句柄的哈希值:

use v5.14;

my %out_fhs = do {
    open my $list_fh, '<', 'list.txt' or die;
    map { 
        state $n = 0;
        $n++;
        chomp;
        open my $fh, '>', "file_$n.txt" or die;
        ( $_, $fh )
        } <$list_fh>;
    };

第二部分使用你刚刚创建的文件句柄的哈希来浏览 details.txt

open my $details_fh, '<', 'details.txt' or die;

DETAIL: while( <$details_fh> ) {
    chomp;
    my( $car ) = m/\A(.*?)_/;
    my $fh = $out_fhs{ $car } || do {
        warn "Car [$car] is not in list.txt. Skipping.\n";
        next DETAIL;
        }

    say $fh $_;
    }

答案 1 :(得分:0)

#!/usr/bin/env perl

use strict;
use warnings;

my %cars;
open my $fh, '<', 'F1.txt' or die $!;
while (<$fh>) {
    chomp;
    $cars{lc $_} = undef;
}
close $fh;

open $fh, '<', 'F2.txt' or die $!;
my $num = 1;
while (<$fh>) {
    if (/\s*([a-z]+)_\d+/i) {
        my $k = lc $1;
        if (exists $cars{$k}) {
            if (!defined $cars{$k}) {
                open my $fd, '>', "file_$num.txt" or die $!;
                $cars{$k} = $fd;
                $num++;
            }
            print {$cars{$k}} $_;
        }
    }
}
close $fh;

答案 2 :(得分:0)

这是生成file_audi.txt等的另一个选项:

use Modern::Perl;

{
    open my $DETAILSIn, '<', 'DETAILS.txt' or die $!;
    my @details = <$DETAILSIn>;

    open my $LISTIn, '<', 'LIST.txt' or die $!;
    while ( my $car = <$LISTIn> ) {
        chomp $car;
        my @recs = grep /^$car\_/i, @details or next;
        open my $fh, '>', "file_$car.txt" or die $!;
        print $fh @recs;
    }
}

当句柄超出范围时,所有打开的文件都会自动关闭。

希望这有帮助!