这个问题有两个部分,一个用于“单线匹配”,一个用于“多线区域匹配”另外,我有一个半工作解决方案,我想在我的解决方案中找到更强大和优雅。
FILE.TXT
YY BANANA, YYZ, ABC YHZ YY1
YY APPLE , YYZ, ABC YHZ YY1
YY ORANGE, YYZ, ABC YHZ YY1
YZ GRAPE , YZZ, ABC YHZ YZ1
BECOME:
YY BANANA, YYZ, ABC YHZ YY1
XY BANANA, XYZ, ABC YHZ XY1
YY APPLE , YYZ, ABC YHZ YY1
XY APPLE , XYZ, ABC YHZ XY1
YY ORANGE, YYZ, ABC YHZ YY1
XY ORANGE, XYZ, ABC YHZ XY1
YZ GRAPE , YZZ, ABC YHZ YZ1
XZ GRAPE , XZZ, ABC YHZ XZ1
请记住,真实文件很大,而YY的例子 - > XY和YZ - > XZ 是完全正确换句话说在我的文件情况下YY,YH,YZ,Y1,Y2,Y3是 我想改为XY,XH,XZ,X1,X2,X3的符号。
我在PERL中做了一些非常原始的事情(将创建一个链接到它 作为展示我在想什么的起点 但是我写的perl脚本并不优雅或一般,需要多个 传递文件。
My Raw Stab .... PERL。 http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/perl-sed-awk/conditional-duplicate/
使用我的原始刺:
MatchDuplicate.pl INPUT.txt YY XY > INPUT2.txt
MatchDuplicate.pl INPUT2.txt YH XH > INPUT3.txt
MatchDuplicate.pl INPUT3.txt Y1 X1 > INPUT4.txt
MatchDuplicate.pl INPUT4.txt Y2 X2 > INPUT5.txt
使用INPUT5.txt ......
FILE.TXT
< some starting marker...startRecord:>
data
data
YY data
YY BANANA, YYZ, ABC YHZ YY1
<some ending record marker>
< some starting marker...startRecord:>
data
data
YY data
YY APPLE , YYZ, ABC YHZ YY1
<some ending record marker>
< some starting marker...startRecord:>
data
data
YY data
YY ORANGE, YYZ, ABC YHZ YY1
<some ending record marker>
< some starting marker...startRecord:>
data
data
YZ data
YZ GRAPE , YZZ, ABC YHZ YZ1
<some ending record marker>
BECOME:
< some starting marker...startRecord:>
data
data
YY data
YY BANANA, YYZ, ABC YHZ YY1
<some ending record marker>
< some starting marker...startRecord:>
data
data
XY data
XY BANANA, XYZ, ABC YHZ XY1
<some ending record marker>
< some starting marker...startRecord:>
data
data
YY data
YY APPLE , YYZ, ABC YHZ YY1
<some ending record marker>
< some starting marker...startRecord:>
data
data
XY data
XY APPLE , XYZ, ABC YHZ XY1
<some ending record marker>
< some starting marker...startRecord:>
data
data
YY data
YY ORANGE, YYZ, ABC YHZ YY1
<some ending record marker>
< some starting marker...startRecord:>
data
data
XY data
XY ORANGE, XYZ, ABC YHZ XY1
<some ending record marker>
< some starting marker...startRecord:>
data
data
YZ data
YZ GRAPE , YZZ, ABC YHZ YZ1
<some ending record marker>
< some starting marker...startRecord:>
data
data
XZ data
XZ GRAPE , XZZ, ABC YHZ XZ1
<some ending record marker>
My Raw Stab: http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/perl-sed-awk/multi-line-conditional-duplicate/
答案 0 :(得分:2)
1:
while(<>) {
say $_;
say $_ if s/$pattern/$replacement/;
}
根据需要添加文件句柄和其他样板文件。
编辑:让我们去寻找一些更通用的东西。
首先,我们将解析出我们的命令行参数,并将我们的替换放入哈希:
$filename = shift @ARGV;
%patterns = ();
while (scalar @ARGV) {
my $pattern = shift @ARGV;
my $replacement = shift @ARGV;
$patterns{$pattern} = $replacement
}
然后对于文件中的每一行,我们将逐字输出该行,然后查看它是否与我们的任何模式匹配。
while (<>) {
say $_;
while (my ($pattern, $replacement) = each %patterns) {
s/$pattern/$replacement/g and say $_ if /^$pattern/;
}
}
答案 1 :(得分:2)
这将解决您的第一个问题:
use strict;
use warnings;
die "usage..." unless @ARGV == 3;
my ($file, $src, $dst) = @ARGV;
open my $fh, '<', $file or die "Can not open $file: $!";
while (<$fh>) {
print;
if (/^$src\b/) {
s/$src/$dst/g;
print;
}
}
close $fh;
查看链接的脚本...您可以轻松地将块注释转换为POD,以便它们有效地成为代码的联机帮助页。然后你可以使用POD::Usage 当用户做一些愚蠢的事情时获取使用信息。
答案 2 :(得分:1)
如果记录结束标记对于所有记录都相同,则可以设置$/
变量,以便<FILE>
一次只读取一条记录。
$\ = "<some ending record marker>\n";
while (<FILE>) {
print $_;
# $_ is a multi-line string so use /m modifier
print $_ if s/$pattern/$replacement/m;
}