在perl中读取输入文件后快速打开多个文件

时间:2012-08-21 21:30:48

标签: perl

我的输入文件(~5k行)格式看起来像这样

foo0: users/user1/temp1 users/user2/temp1 4.0
foo1: users/user2/temp1 users/user4/temp2 users/user4/temp1 1.0
foo2: users/user1/temp3 users/user2/temp3 2.0
foo4: users/user4/temp5 users/user2/temp6 users/user1/temp1 users/user3/temp1 4.0

我的脚本需要做的是查看每一行,抓住每个路径,打开文件和放大器。根据它检查内部的东西。

例如:对于第1行,脚本必须打开 user1 .txt并在user1.txt中搜索temp1并执行某些操作。然后继续 user2 .txt并在内部查找temp1并执行某些操作。

对于第2行:打开 users2 .txt并搜索temp1;打开 users4 .txt并搜索temp2;打开 users4 .txt并搜索temp1。

最快捷的方式是什么。我目前一个接一个地打开和关闭,这似乎需要很长时间。感谢任何帮助,谢谢!

2 个答案:

答案 0 :(得分:-1)

我会做这样的事情:

#! /usr/bin/perl

use warnings;
use strict;

while ( <> ) { 

    ## Remove last newline character.
    chomp;

    ## Split line with spaces and save paths (all strings but the first and
    ## last one).
    my @paths = split;
    @paths = @paths[ 1 .. $#paths - 1 ];

    ## For each path...
    for my $path ( @paths ) { 

        ## Split with a slash, get second field and try to open it. 
        my @elements = split m|/|, $path;
        open my $fh, q|<|, $elements[1] or die $!; 

        ## Read line by line searching for the third field of the path, do
        ## something if found. You can add a 'last' instruction if you wish.
        while ( my $line = <$fh> ) { 
            chomp;
            if ( $line =~ m/\Q${elements[2]}\E/ ) { 
                ## Do something;
            }   
        }   

        close $fh or warn $!; 
    }   
}

答案 1 :(得分:-2)

嗯,在普通系统上,硬盘数据传输速度是限制。但有些方法可能会给你带来优势:

多线程

如果您担心在此程序运行时硬盘可能处于空闲状态,或者您从多个物理驱动器读取数据,则可能需要尝试多线程处理。你应该注意,这个可以让你的程序运行得更慢(a)如果实现错误或(b)如果你的硬盘读头必须跳太多了。

  1. 使用pipe函数打开 n 管道,其中 n 是线程数。
  2. 来自主(“ boss ”)主题的
  3. fork n 次。
    1. 每个工作线程关闭所有不相关的管道
  4. boss线程读取您的输入文件,并将每个命令依次传递给不同的进程 。这样,所有工作进程都有相同的工作量。
  5. 工作线程会进行搜索等。
  6. 如果您之前未使用fork进行多线程处理,则此解决方案将不适合您。

    并且,如上所述,当你对每个文件的计算都很昂贵(当计算/搜索的时间与阅读时间相当时),这有点不太可能导致之外的正面结果如果您的脚本耗尽了大量CPU并且您有多个处理器,这可能会有所帮助。

    提出更好的算法

    • 您在每个文件中搜索的内容和方式是什么?你只是将一个正则表达式与每一行匹配,然后执行一些代码吗?什么代码?正则表达式过于复杂吗?
    • 你可以使用一些启发式来跳过文件的某个部分吗?
    • 你试过Tie::File吗?这样可以避免将文件加载到内存中,这可能有所帮助。
    • 基准您的脚本了吗?有关简介,请参阅此tutorial on perl.com。哪些部分运行缓慢?
    • 您能否降低程序的算法复杂度?即:你在任何文件上迭代两次?这可能不是最理想的。