arrays - 多次迭代一个文件,每次查找一个正则表达式并返回一行(perl)

标签 arrays regex file perl while-loop

我有一个文件,其中 4 列包含约 9 万行文本。

col1    col2     col3    value1
...
col1    col2     col3    value90000

第二个文件包含约 200 行,每一行对应于较大文件第 4 列中的一个值。

value1
value2
...
value200

我想从较小的文件中读取每个值,在较大的文件中找到相应的行,然后返回该行。我编写了一个 perl 脚本,它将小文件中的所有值放入一个数组中,然后使用每个值作为正则表达式来迭代该数组,以搜索较大的文件。经过一些调试后,我觉得它几乎可以工作,但我的脚本只返回与数组的最后一个元素相对应的行。

这是我的代码:

open my $fh1, '<', $file1 or die "Could not open $file1: $!";

my @array = <$fh1>;
close $fh1;

my $count = 0;

while ($count < scalar @array) {
    my $value = $array[$count];
    
    open my $fh2, '<', $file2 or die "Could not open $file2: $!";
    
    while (<$fh2>) {
        if ($_ =~ /$value/) {
            my $line = $_;
            print $line;
            }
    }
    close $fh2;
    $count++;   
}

这仅返回:


col1     col2     col3   value200

我可以让它打印数组的每个值,所以我知道它正在正确迭代,但它并没有按照我的预期使用每个值来搜索更大的文件。我还可以将数组中的任何值插入 $value 变量并返回相应的行,这样我就知道这些行在那里。我怀疑我的错误可能与以下任一有关:

  1. 数组元素中的换行符,因为除最后一个元素之外的所有元素都有换行符。我尝试过 chomp 但得到了相同的结果。

  • 与我处理打开/关闭第二个文件的方式有关。我尝试过移动或删除 close 命令,但这要么会破坏代码,要么没有帮助。
  • 最佳答案

    您应该只读取 90k 行文件一次,并按照每行的第四列检查另一个文件中的每个值,而不是较小文件的每行读取整个大文件一次:

    #!usr/bin/env perl
    use warnings;
    use strict;
    use feature qw/say/;
    
    my ($file1, $file2) = @ARGV;
    
    # Read the file of strings to match against
    open my $fh1, '<', $file1 or die "Could not open $file1: $!";
    my %words = map { chomp; $_ => 1 } <$fh1>;
    close $fh1;
    
    # Process the data file in one pass
    open my $fh2, '<', $file2 or die "Could not open $file2: $!";    
    while (my $line = <$fh2>) {
        chomp $line;
        # Only look at the fourth column
        my @fields = split /\s+/, $line, 4;
        say $line if exists $words{$fields[3]};
    }
    close $fh2;
    

    请注意,这使用与最后一列的直接字符串比较(通过哈希键查找)而不是正则表达式匹配 - 您的示例数据看起来就是所需要的。如果您使用实际的正则表达式,请告诉我,我将更新答案。


    你的代码看起来确实应该可以工作,只是效率非常低。事实上,在调整示例数据以便多行匹配之后,它确实为我打印出了多行。

    关于arrays - 多次迭代一个文件,每次查找一个正则表达式并返回一行(perl),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64378358/

    相关文章:

    regex - 为什么 Bash 模式匹配 ?(*[[ :class:]])foobar slow?

    regex - 正则表达式是否尝试匹配文本中字符之间的位置?

    c# - 如何将字节数组转换为字符串?

    c - 如何使用内存分配通过指针在数组中存储值

    php - 单词与单词的分离(正则表达式和 PHP)

    java - 在Java中使用文本文件携带命令

    java - 在 Java 文件中间写入字节的最佳方式

    python从文件中读取数据

    java - 如何计算二维数组中每一列的总和?

    C++ strcpy_s 在复制到新的 char 数组时抛出错误