我正在尝试根据列值将一个大文件(大约有1760万个数据)拆分成6-7个小文件。目前,我正在使用sql bcp实用程序将所有数据转储到一个表中并创建单独的使用bcp out实用程序的文件。
但有人建议我使用Perl,因为它会更快,你不需要为此创建一个表。因为我不是一个perl家伙。我不知道如何在perl中做到这一点。 任何帮助..
INPUT文件:
inputfile.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|...
答案 0 :(得分:4)
保持输出文件句柄的哈希是最简单的,由文件名键入。这个程序显示了这个想法。每条记录开头的数字用于创建它所属文件的名称,并打开该名称的文件,除非我们已经有了文件句柄。
处理完所有数据后,所有句柄都会关闭。 use autodie
会抓住任何错误,因此无需明确检查open
,print
和close
来电。
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,但现在改变它的方法是迟到的
答案 1 :(得分:1)
我认为,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);
}
我没有明确地测试过这个,但它应该让你朝着正确的方向前进。
答案 2 :(得分:1)
$ perl -F'|' -lane '
$key = $F[0];
$fh{$key} or open $fh{$key}, ">", "$key.txt" or die $!;
print { $fh{$key} } $_
' inputfile.txt
答案 3 :(得分:1)
perl -Mautodie -ne'
sub out { $h{$_[0]} ||= open(my $f, ">", "$_[0].txt") && $f }
print { out($1) } $_ if /^(\d+)/;
' file