搜索非常大的文本文件和将大量术语中的任何一个与另一个文件相匹配的输出行的最有效方法

发布于 2024-12-17 04:26:09 字数 111 浏览 1 评论 0原文

我有大约 1500 万行文件。我还有另一个文件,大约有 500,000 行。我想保留大文件中特定字段与第二个文件中的行匹配的行。大文件以制表符分隔。

例如,您将如何在 Perl 中执行此操作?

I have ~15 million line file. I have another file with around 500,000 lines. I want to keep lines from the large file where a particular field matches the line in the second file. The large file is tab delimited.

How would you do this in Perl, for example?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白芷 2024-12-24 04:26:09

您可能会受益于使用 csv 模块解析大文件中的数据。您必须自己做出判断,这也可能是矫枉过正,而且带来的麻烦超过了它的价值。请注意,下面使用的 Text::CSV_XS 可能会更改您的数据以符合 csv 标准,并且有很多选项可以调整输出的外观。

这是一个可能帮助您入门的基本脚本。

use strict;
use warnings;
use autodie;
use Text::CSV_XS;

open my $lookup, '<', "lookupfile";
my %lookup;
while (<$lookup>) {
    next if /^\s*$/;   # remove empty lines
    chomp;             # remove newline
    $lookup{$_} = 1;
}
close $lookup;

my $csv = Text::CSV_XS->new ({
    binary    => 1, 
    eol       => $/,
    sep_char  => "\t",
});
open my $bigfile, '<', 'bigfile';
while (my $row = $csv->getline ($bigfile)) {
    if (defined ($lookup{$row->[0]})) {
        $csv->print(\*STDOUT, $row);
    }
}

如果您确信数据不会包含嵌入的选项卡,则可以简单地拆分选项卡上的行,而不是使用 Text::CSV_XS:

while (<$bigfile>) {
    chomp;
    my @row = split /\t/;
    if (defined $lookup{$row[0]}) {
        print "$_\n";
    }
}

You might benefit from using a csv module to parse the data from the large file. It might also be overkill, and more trouble than it's worth, that you must judge for yourself. Be aware that Text::CSV_XS used below may alter your data to comply to csv standards, and there are many options to tweak what your output looks like.

This is a basic script that might get you started.

use strict;
use warnings;
use autodie;
use Text::CSV_XS;

open my $lookup, '<', "lookupfile";
my %lookup;
while (<$lookup>) {
    next if /^\s*$/;   # remove empty lines
    chomp;             # remove newline
    $lookup{$_} = 1;
}
close $lookup;

my $csv = Text::CSV_XS->new ({
    binary    => 1, 
    eol       => $/,
    sep_char  => "\t",
});
open my $bigfile, '<', 'bigfile';
while (my $row = $csv->getline ($bigfile)) {
    if (defined ($lookup{$row->[0]})) {
        $csv->print(\*STDOUT, $row);
    }
}

If you feel secure that your data will not contain embedded tabs, you might get away with simply splitting the line on tabs, instead of using Text::CSV_XS:

while (<$bigfile>) {
    chomp;
    my @row = split /\t/;
    if (defined $lookup{$row[0]}) {
        print "$_\n";
    }
}
星星的轨迹 2024-12-24 04:26:09

我将填充一个以第二个文件中的值为键的哈希值。将值设置为 1

然后,我会执行一个简单的 while() 循环,在关键字段的哈希中进行查找。如果哈希中有条目,则打印该行。否则继续。

Perl 的散列查找非常快,执行 1500 万次应该没问题。

I'd populate a hash keyed on the values from the second file. Set the values to 1.

Then I'd do a simple while(<FILE>) loop doing lookups in the hash on the key field. If there is an entry in the hash, print the line. Else move on.

Perl's hash lookups are pretty quick, doing it 15 million times ought to be alright.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文