【问题标题】:splitting a large file into small files based on column value in perl根据perl中的列值将大文件拆分为小文件
【发布时间】:2014-04-29 16:41:00
【问题描述】:

我正在尝试根据列值将一个大文件(大约有 1760 万个数据)拆分为 6-7 个小文件。目前,我正在使用 sql bcp 实用程序将所有数据转储到一个表中并创建单独的使用 bcp out 实用程序的文件。

但是有人建议我使用 Perl,因为它会更快,而且您不需要为此创建表。因为我不是 perl 人。我不知道如何在 perl 中做到这一点。 任何帮助..

输入文件:

输入文件.txt

0010|name|address|city|.........
0020|name|number|address|......
0030|phone no|state|street|...

输出文件:

0010.txt

0010|name|address|city|.........

0020.txt

0020|name|number|address|......

0030.txt

0030|phone no|state|street|...

【问题讨论】:

    标签: perl


    【解决方案1】:

    保存输出文件句柄的散列是最简单的,以文件名为键。这个程序显示了这个想法。每条记录开头的数字用于创建其所属文件的名称,除非我们已经有文件句柄,否则该名称的文件会被打开。

    处理完所有数据后,所有句柄都将关闭。 use autodie 会捕获任何错误,因此无需显式检查 openprintclose 调用。

    use strict;
    use warnings;
    use autodie;
    
    open my $in_fh, '<', 'inputfile.txt';
    
    my %out_fh;
    
    while (<$in_fh>) {
      next unless /^(\d+)/;
      my $filename = "$1.txt";
      open $out_fh{$filename}, '>', $filename unless $out_fh{$filename};
      print { $out_fh{$filename} } $_;
    }
    
    close $_ for values %out_fh;
    

    注意 close 把我抓到这里是因为,与大多数在 $_ 上工作的运算符不同,如果你不传递任何参数,一个裸露的 close 将关闭 当前选择 em> 文件句柄。这是一个糟糕的选择 IMO,但现在改变它为时已晚

    【讨论】:

      【解决方案2】:

      我想,1760 万行将是一个相当大的文件。使用 perl 处理它仍然会很慢。

      也就是说,你会想要下面这样的东西:

      use strict;
      use warnings;
      
      my $input = 'FILENAMEHERE.txt';
      my %results;
      
      open(my $fh, '<', $input) or die "cannot open input file: $!";
      while (<$fh>) {
        my ($key) = split '|', $_;
        my $array = $results{$key} || [];
        push $array, $_;
        $results{$key} = $array;
      }
      
      for my $filename (keys %results) {
        open(my $out, '>', "$filename.txt") or die "Cannot open output file $out: $!";
        print $out, join "\n", $results{$filename};
        close($out);
      }
      

      我没有明确测试过,但它应该能让你朝着正确的方向前进。

      【讨论】:

        【解决方案3】:
        $ perl -F'|' -lane '
            $key = $F[0];
            $fh{$key} or open $fh{$key}, ">", "$key.txt" or die $!;
            print { $fh{$key} } $_
          ' inputfile.txt
        

        【讨论】:

        • 请评论为什么应该删除这个答案
        【解决方案4】:
        perl -Mautodie -ne'
          sub out { $h{$_[0]} ||= open(my $f, ">", "$_[0].txt") && $f }
          print { out($1) } $_ if /^(\d+)/;
        ' file
        

        【讨论】:

        • &amp;out 是否总是返回一个文件句柄?
        • @Zaid 是的,除非它死了
        • 请评论为什么应该删除这个答案。
        猜你喜欢
        • 2019-04-30
        • 2015-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-23
        • 1970-01-01
        • 1970-01-01
        • 2014-06-06
        相关资源
        最近更新 更多