Perl合并两个文件并删除重复文件——这是一个令人困惑的问题



我目前正试图在perl脚本中合并两个不同的文本文件,但这比这要复杂一些。

问题(为了便于解释,稍作改动):

我有两个不同的文本文件,一个名为dog1.txt,一个名称为dog2.txt(如下所示)。

dog1.txt
poodle     8888
jackrussel    5743
beagle     6784
dog2.txt 
spaniel    9843
poodle    3756
germanshepard    3267
beagle    3478  

正如你所看到的,贵宾犬和比格犬都包含在两个文本文件中,但它们有不同的四位数代码。

我想要的是创建一个新文件,将这两个文件合并在一起。如果有任何重复的文件,如贵宾犬和小猎犬,我希望新文件包含与贵宾犬和比格犬相关的四位数字,来自dog.txt文件,而不是dog2.txt。

新文件需要看起来像这样(这与狗名的顺序无关,与它们相关的数字需要正确):

final_dog.txt
poodle    8888
germanshepard    3267
jackrussel    5743
beagle    6784
spaniel    9843

我尝试过许多不同的解决方案,但没有一个能可靠地按照我需要的方式工作

非常感谢任何帮助,谢谢

您基本上想要打印遇到的第一个实例。因此,您可以使用标准习语来删除重复项。

perl -lane'print if !$seen{$F[0]}++' dog1.txt dog2.txt >final_dog.txt

这种方法使用最少的内存。它还尽可能早地开始产生输出(如果您正在管道输出,则非常有用)。


要满足新要求,请使用

perl -lane'print if @F==2 && $F[1]=~/^d+z/ && !$seen{$F[0]}++' 
dog1.txt dog2.txt >final_dog.txt

作为一行:

perl -MData::Dumper -lwe '
$d = pop;             # save filename for later
%d = map split, <>;   # process dog1.txt
push @ARGV, $d;       # put the second file name back
while (<>) {          # add new entries, unless already defined
my ($dog,$num) = split; $d{$dog} //= $num; 
} 
print Dumper %d' dog1.txt dog2.txt

输出:

$VAR1 = {
'poodle' => '8888',
'spaniel' => '9843',
'germanshepard' => '3267',
'beagle' => '6784',
'jackrussel' => '5743'
};

此解决方案使用由菱形运算符<>@ARGV中的参数执行的隐式打开。定义的//=或赋值运算符不会覆盖已定义的值。

正如ikegami聪明地指出的那样,可以通过反转参数来消除检查值的必要性。然后这就变得非常简单:

perl -MData::Dumper -lwe '
%d = map split, <>; 
print Dumper %d' dog2.txt dog1.txt   # note reversed args

我将把打印语句留给您,因为您没有指定您的文件是制表符分隔还是其他什么。但你可能会做一些类似的事情:

print join "t", $_, $d{$_} for keys %d;      # tab separated
printf "%-20s %sn", $_, $d{$_} for keys %d;  # fixed width

请注意,这是一个破坏性的解决方案,不像池上春树的答案那样保留了原始格式。

这个解决方案满足了您的要求,此外,它还满足了每行上的值可能包含空格的情况。

use strict;
use warnings;
my %data;
for my $file (qw/ dog2.txt dog1.txt /) {
open my $fh, '<', $file or die $!;
while (<$fh>) {
$data{$1} = $2 if /(S+)s+(S(?:.*S)?)/;
}
}
while (my ($key, $val) = each %data) {
print "$key $valn";
}

输出

poodle 8888
spaniel 9843
germanshepard 3267
beagle 6784
jackrussel 5743

相关内容

最新更新