读取两个文件,并将一个文件中的模式替换为另一个文件中的数据

时间:2015-08-28 10:11:04

标签: regex perl substitution

我正在运行一个perl脚本,它从第一个文件获取数据,匹配第二个文件中的模式,并在找到匹配时替换为数据(第一个文件)。

当我运行脚本时,第二个文件中没有替换。我正在开发Windows。

use strict;
use warnings;

my ($value1,$value2);
open(file1, "data1.txt") or die "Cannot open file.\n";
open(file2, "data2.txt") or die "Cannot open file.\n";

while (<file1>) {
    $value1 = $_;
    chomp($value1);
    my @parts = split(/ +/, $value1); 
    $value2 = <file2>;

    $value2 =~ s/ threshold1/ $parts[0]/;
    $value2 =~ s/ threshold2/ $parts[1]/;
    $value2 =~ s/ threshold3/ $parts[1]/;
    }
close(file1);
close(file2);

文件1

10
20
30

文件2

a=1 b=2 c=3
d=4 e=5 f=6
g = threshold1 h=7 i=8
lines
lines
j= 9 k=11 
l = threshold2
lines
lines
m = threshold3
lines
lines

我需要将第二个文件中的threshold1,threshold2,threshold3替换为第一个文件中的值。

3 个答案:

答案 0 :(得分:1)

以下是对您的代码的一些修改,现在可以根据需要进行修改:

use strict;
use warnings;

使用lexically scoped 3参数open(现在推荐的做法):

open my $file1, '<', '1.txt' or die "Cannot open file\n";
open my $file2, '<', '2.txt' or die "Cannot open file\n";

然后将file1中的每一行添加到数组@parts的末尾:

my @parts;
push @parts, $_ while(<$file1>);    
chomp(@parts);

然后只需逐行阅读file2并进行适当替换,然后您就可以通过将每一行($_)打印到STDOUT来查看每行发生了什么:

while (<$file2>) {
    chomp;
     s/threshold1/$parts[0]/;
     s/threshold2/$parts[1]/;
     s/threshold3/$parts[2]/; # I assume you want '30' here?
     print  "$_\n";
}

所以输出是:

a=1 b=2 c=3
d=4 e=5 f=6
g = 10 h=7 i=8
lines
lines
j= 9 k=11 
l = 20
lines
lines
m = 30
lines
lines

请告诉我这是否确实是您尝试做的事情,我可以解释我所做的更改

答案 1 :(得分:0)

问题是您正在从两个文件中读取行并成对处理它们。因此,数据文件中的第一行将从阈值文件的第一行获取值,从阈值文件的第二行获取第二行等。当到达两个文件的第三行时,循环将结束,因为没有更多数据阈值文件

该程序将满足您的需求。它将data1.txt中的所有值读入数组@thresholds,并将文件data2.txt的内容拉入标量$data。然后,匹配正则表达式模式threshold\d+的字符串将替换为@threshold的一个元素,方法是从字符串末尾的数字中减去一个,并将其用作数组的索引。所以threshold1$threshold[0]取代,threshold2取代$threshold[1]等。它最终重新打开数据文件以进行输出并将修改后的字符串写入其中

程序期望两个文件的路径作为命令行上的参数,因此应该以{{1​​}}

运行
perl thresh_replace.pl data1.txt data2.txt

输出

use strict;
use warnings;
use v5.10.1;
use autodie;

my ($thresholds_file, $data_file) = @ARGV;

my @thresholds = do {
    open my $fh, '<', $thresholds_file;
    local $/;
    split ' ', <$fh>;
};

my $data = do {
    open my $fh, '<', $data_file;
    local $/;
    <$fh>;
};

$data =~ s/threshold(\d+)/$thresholds[$1-1]/g;

{
    open my $fh, '>', $data_file;
    print $fh $data;
}

答案 2 :(得分:0)

use strict;
use warnings;
use Tie::File; #This module can use for reading and writing on the same file

my $File1 = "File1.txt";
my $File2 = "File2.txt";

my @array;
tie @array, 'Tie::File', $File2 || die "Error: Couldn't tie the \"$File1\" file: $!";
my $len = join "\n", @array;
open(FILE, $File1) || die "Couldn't open the file $File2: $!\n";

#Threshold and line count matches
my $lineCount = '1';
while(<FILE>)
{
    my $line = $_;
    if($line!~/^$/) { chomp($line);

    #Replace threshold with the first file values
    $len=~s/threshold$lineCount/$line/i; }
    $lineCount++;
}
@array = split/\n/, $len;
untie @array;
close(FILE);