【问题标题】:compare files and storing similar data into different files比较文件并将相似的数据存储到不同的文件中
【发布时间】:2012-08-14 18:29:27
【问题描述】:
**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;              
      }   
    } 
  }

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

【问题讨论】:

    标签: regex string perl


    【解决方案1】:

    这是多路复用的基本练习。我们甚至在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 $_;
        }
    

    【讨论】:

    • 谢谢@brain d foy 将升级我的 Perl 版本并在上面尝试一下。
    【解决方案2】:

    这是另一个生成 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;
        }
    }
    

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

    希望这会有所帮助!

    【讨论】:

    • 谢谢@kenosis.. 是他们没有模块的方式吗???我正在尝试安装这些模块,但我没有成功。
    • @unkaitha - 以上将在没有use Modern::Perl; 杂注的情况下运行,其中包括use strict;use warnings;。但是,最好在脚本中至少包含后两个 pragma。
    • 是的,我使用了严格和警告,即使这样它也没有生成任何文件。
    • @unkaitha - 我不确定您遇到了什么问题,因为这些文件是在我的系统上生成的,位于 DETAILS.txt 和 LIST.txt 所在的目录中。从您上次的评论中,我注意到您对 cdtits 的脚本有同样的问题。
    【解决方案3】:
    #!/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;
    

    【讨论】:

    • 非常感谢@cdtits 的回答,但是文件已生成并且它们都是空的...我想知道将详细信息打印到生成文件中的行???
    • @unkaitha:打印 {$cars{$1}} $_;你必须“使用严格;”将结果打印到每个文件。
    • @unkaitha:区分大小写?现在将其转换为更低
    • @unkaitha:它在我的机器上运行良好。你可以使用 print 来调试自己吗?
    • @unkaitha:尝试取消注释打印行?
    猜你喜欢
    • 1970-01-01
    • 2022-10-15
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    相关资源
    最近更新 更多