0
**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

我想将每辆车的详细信息分成不同的文件,即在这种情况下我想要 4 个文件,其中兰博、奥迪、宝马和 merc 详细信息在不同的文件中,如 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;              
      }   
    } 
  }

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

4

3 回答 3

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 $_;
    }
于 2012-08-14T10:29:27.890 回答
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;
于 2012-08-13T04:11:21.697 回答
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;
    }
}

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

希望这可以帮助!

于 2012-08-13T05:55:43.317 回答