下表表示我有一个制表符分隔的文件。
1 2 3
A Jack 01
A Mary 02
A Jack 03
B Mary 04
B Mike 05
B Mary 06
C Mike 07
C Mike 08
C Jack 09
我想解析这个文本文件并根据第1列和第1列创建多个文本文件。 2.每个文本文件将包含数据(第3列),其中第1列和第2列是相同的。因此,在此示例中,数据将按如下方式组织:
> file1.txt
A Jack 01
A Jack 03
> file2.txt
A Mary 02
> file3.txt
B Mary 04
B Mary 06
> file4.txt
B Mike 05
> file5.txt
C Mike 07
C Mike 08
> file6.txt
C Jack 09
#What would be the best way to tackle this? The only method I can think of is to create a 2-dimensional array and then comparing every row/col pair.
编辑:以下代码似乎有效。还有更好的选择吗?
#!/usr/bin/perl
use strict;
use warnings;
my $file = "/home/user/Desktop/a.txt";
my @array =();
open(FILE, $file) || die "cannot open file";
while(my $line = <FILE>){
my @row = split("\t", $line);
my $two = $row[1]."\t".$row[2];
push(@array, $two);
}
close FILE;
@array = uniq(@array);
my $counter = 0;
foreach my $x (@array){
#unique tab
open(SEC, $file) || die "cannot open 2nd time\n";
while(my $line = <SEC>){
if($line =~ /($x)/){
my $output = "txt".$counter.".txt";
print "hit!\n";
open(OUT, '>>', $output) || die "cannot write out";
print OUT $line."\n";
close OUT;
}
}
$counter++;
}
close SEC;
sub uniq {
return keys %{{ map { $_ => 1 } @_ }};
}
我知道如何通过命令行对其进行排序(sort -t:-k1,2 a.txt),但我想知道如何在perl中编写它并写出多个文件。
答案 0 :(得分:1)
连接两个第一个字段并将它们用作哈希键。每个哈希键指向一个数组,您可以在其中添加所有相关的行:
#!/usr/bin/perl
use strict;
use warnings;
open my $fh, "/home/johan/Desktop/tabdel.txt"
or die $!;
<$fh>; # Skip header
my $data = {};
while (my $line = <$fh>) {
# match the fields
next unless $line =~ /^(\S+)\s+(\S+)\s+\S+/;
# append $line to the hash value, key is the concatenated two first fields:
push @{ $data->{"$1 $2"}->{'lines'} }, "$line";
}
my $file_count = 0;
foreach my $key (sort keys %{$data}) {
my $qfn = "file".(++$file_count).".txt";
open(my $fh, '>', $qfn)
or die $!;
foreach my $line (@{ $data->{$key}->{'lines'} }) {
print $fh $line;
}
}
答案 1 :(得分:1)
也许以下内容会有所帮助:
use strict;
use warnings;
my %hash;
my $n = 1;
while (<>) {
next if $. == 1;
my @a = split;
if ( !exists $hash{ $a[0] }{ $a[1] } ) {
open $hash{ $a[0] }{ $a[1] }, '>', 'file' . $n++ . '.txt' or die $!;
}
print { $hash{ $a[0] }{ $a[1] } } $_;
}
用法:perl script.pl inFile.txt
确认ikegami关于数据集很大的可能用完文件句柄的观点,这里有一个选项,用于收集哈希值的结果,然后将结果打印到文件中(用法与上面的脚本):
use strict;
use warnings;
my ( %hash, %seen );
my $n = 0;
while (<>) {
next if $. == 1;
my ( $key, $elem ) = /(.+\s+)(\d+)\Z/;
push @{ $hash{$key} }, $elem;
}
for my $key ( sort { $hash{$a}->[0] <=> $hash{$b}->[0] } keys %hash ) {
$n++ if !$seen{$key}++;
open my $fh, '>', 'file' . $n . '.txt' or die $!;
print $fh "$key$_\n" for @{ $hash{$key} };
}