我的输入文件(~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。
最快捷的方式是什么。我目前一个接一个地打开和关闭,这似乎需要很长时间。感谢任何帮助,谢谢!
答案 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)如果你的硬盘读头必须跳太多了。
pipe
函数打开 n 管道,其中 n 是线程数。fork
n 次。
如果您之前未使用fork
进行多线程处理,则此解决方案将不适合您。
并且,如上所述,当你对每个文件的计算都很昂贵(当计算/搜索的时间与阅读时间相当时),这有点不太可能导致除之外的正面结果如果您的脚本耗尽了大量CPU并且您有多个处理器,这可能会有所帮助。
Tie::File
吗?这样可以避免将文件加载到内存中,这可能有所帮助。