【发布时间】:2014-03-06 16:46:37
【问题描述】:
基于映射文件,我需要搜索一个字符串,如果找到,则将替换字符串附加到行尾。 我正在逐行遍历映射文件,并使用下面的 perl 单行,附加字符串。
问题:
1.Huge find & replace Entries: 但问题是映射文件有大量的条目(约 7000 个条目),而 perl 单行器每个条目需要约 1 秒,这归结为到 ~ 1 小时完成整个更换。
2.不是简单的查找和替换:它不是简单的查找和替换。它是 - 如果找到字符串,则将替换字符串附加到 EOL。 如果没有有效的方法来处理这个,我什至会考虑替换而不是追加。
我的是在 Windows 7 64 位环境中,我使用的是活动 perl。不支持 *unix。
文件示例
Map.csv
findStr1,RplStr1
findStr2,RplStr2
findStr3,RplStr3
.....
findStr7000,RplStr7000
input.csv
col1,col2,col3,findStr1,....col-N
col1,col2,col3,findStr2,....col-N
col1,col2,col3,FIND-STR-NOT-EXIST,....col-N
output.csv(预期输出)
col1,col2,col3,findStr1,....col-N,**RplStr1**
col1,col2,col3,findStr1,....col-N,**RplStr2**
col1,col2,col3,FIND-STR-NOT-EXIST,....col-N
Perl 代码片段
单线
perl -pe '/findStr/ && s/$/RplStr/' file.csv
open( INFILE, $MarketMapFile ) or die "Error occured: $!";
my @data = <INFILE>;
my $cnt=1;
foreach $line (@data) {
eval {
# Remove end of line character.
$line =~ s/\n//g;
my ( $eNodeBID, $MarketName ) = split( ',', $line );
my $exeCmd = 'perl -i.bak -p -e "/'.$eNodeBID.'\(M\)/ && s/$/,'.$MarketName.'/;" '.$CSVFile;
print "\n $cnt Repelacing $eNodeBID with $MarketName and cmd is $exeCmd";
system($exeCmd);
$cnt++;
}
}
close(INFILE);
【问题讨论】:
-
花费这么长时间的部分原因是您正在为循环中的每一行创建一个新的 Perl 进程。你不应该那样做。
-
您要匹配的字符串是否总是在 CSV 的第 4 列中?
-
@ThisSuitIsBlackNot 是。搜索字符串列位置始终固定
-
您提到有大约 7000 个条目并且文件“巨大”;你能提供更多关于这意味着什么的信息吗?一个典型的条目是多长的字符?查找字符串有多长?替换字符串有多长?查找字符串真的只是一个字符串还是有任何正则表达式元字符,例如:“$.\”?所有这些因素都可能影响性能。
-
@benrifkah 不仅如此,OP 正在读取整个输入文件 7000 次,映射文件中的每个条目一次。