我有一个制表符分隔的文件:
AA 11
AA 22
AA 11
AA 22
BBB 44
BBB 77
BBB 44
BBB 77
我想打印文件的不同行:
AA 11
AA 22
BBB 44
BBB 77
我写了这个Perl脚本来做到这一点:
#!/usr/bin/perl
$file1=$ARGV[0];
%record;
open(FP1,"$file1");
while($s1=<FP1>)
{
chomp($s1);
@array= split(/\t/,$s1);
$name1=$array[0];
$name2=$array[1];
push @{$record{$name1}{trs}}, $name2;
$ref=\%record;
}
for $name1 ( sort { $a <=> $b } keys %record )
{
my $name2 = $$ref{$name1}{trs};
print "$name1\t$name2\n";
}
但它不起作用。有人可以帮忙吗?
答案 0 :(得分:3)
如果您不想更改订单行,则不必先将整个文件读入内存,
use strict;
use warnings;
use autodie;
my $file1 = $ARGV[0];
my %seen;
open(my $FP1, "<", $file1);
while (my $s1 = <$FP1>) {
next if $seen{$s1}++;
print $s1;
}
答案 1 :(得分:1)
主要问题是您将AA
记录存储在名为@{$record{'AA'}{trs}}
的数组中(即@{$record{'AA'}->{'trs'}}
),但是当您打印这些记录时,您不会迭代该数组,你只是尝试将其作为标量读取。
您的文件以制表符分隔的这一事实似乎并不相关,因为如果两条记录不同,您显然会认为两条线是不同的。因此,您不必担心将线路转换为&#34;记录&#34;用于处理。
(即使除此之外,你还有很多不必要的代码 - 例如,根本没有理由创建$ref
。)
您实际上可以省去Perl,并使用标准sort
实用程序:
sort -u <INPUT_FILE >OUTPUT_FILE
答案 2 :(得分:1)
如果行与完全匹配,则您需要的只是来自List::MoreUtils
的uniq
函数
use strict;
use warnings;
use List::MoreUtils 'uniq';
my @data = <DATA>;
chomp @data;
print "$_\n" for uniq @data;
__DATA__
AA 11
AA 22
AA 11
AA 22
BBB 44
BBB 77
BBB 44
BBB 77
<强>输出强>
AA 11
AA 22
BBB 44
BBB 77
如果您无法安装List::MoreUtils
并且不能安装uniq
,那么您必须编写类似这样的内容
use strict;
use warnings;
use List::MoreUtils 'uniq';
my @data = <DATA>;
chomp @data;
my (@unique, %unique);
for (@data) {
push @unique, $_ unless $unique{$_}++;
}
print "$_\n" for @unique;
输出与前一个示例相同。