将文件 B 中的标签替换为文件 A 中的值

将文件 B 中的标签替换为文件 A 中的值

我正在寻求 Perl 方面的帮助。我已经构建了大部分代码,但我发现其中一部分特别具有挑战性。

如果文件A:

tag1=value1
tag2=value2

和文件B:

value1=<tag1>
value2=<tag2>

伪代码:

open file 1
open file 2
 read line of data from file 1 while data exists
   change the equal sign to a space ( tag1=value1 becomes tag1 value1)
   separate the line into two variables

[魔法发生在这里我将 FileB 中的值更改为 FileA 中的实际值(请参见下面的示例)]

close file 2
close file 1

所以,我尝试了几件事,用谷歌叔叔(和这里)研究了这个问题。我知道有一种简单的方法可以使用单个命令行来执行此操作(

prompt> gawk '{sub(/=/," ")}1' [path]/[FileA] | 
    gawk '{system ("perl -pi -e \x27s/"$1"/"$2"/g\x27 [path]/[FileB]")}' 

),但我不想那样做,而是尝试在我的 Perl 程序中实现它,因为我喜欢让自己的事情变得更困难:-p。

因此,例如,如果 FileA 包含

<tag1>=192.192.2.3
<tag2>=5400

并且 FileB 包含

connect IP=<tag1>
connect port=<tag2>

在这个程序的最后,我希望 FileB 包含

connect IP=192.192.2.3
connect port=5400

我了解如何在程序中执行替换,但是,我很难让它更新文件。

任何提示都会受到欢迎;我什至不需要完整的解决方案,只需要一些可以为我指明正确方向的东西。

这是不是家庭作业。

答案1

听起来您想根据第一个文件中的数据构建哈希表,然后用它来修改第二个文件。粗略地说,这可能会给你一些想法

my %my_tags;

while (<$fh1>) {
    chomp;
    my ($tag, $value) = split /=/;
    $my_tags{$tag} = $value;
}

while (<$fh2>) {
    s/(\w+)=(\S+)/$1=$my_tags{$2}/;
    print;
}

如果您需要更多的替换魔法,请查看如何使用/e评估标志。

答案2

在这种情况下我会做如下:

read the tag-file (A) into a hash %tag
read the text-file into an array @text
for keys tag-hash 
    substitute all tags in the array

write the array @text to the textfile

或者:

#!/usr/bin/perl
use strict;

my @text;
my %tags;
open (my $TAGS,'<',"fileA") or die "horribly";
while(<$TAGS>){
    if (/<(.*)>=(.*)/){
        $tags{$1}=$2;
    }
}
close $TAGS;
open (my $TXT,'<',"fileB") or die "no B";
@text=<$TXT>;
close $TXT;

for my $key (keys %hash) {
    for (@text){
        s/<$key>/$tags{$key}/;
    }
}

open (my $TXT,'>',"fileB") or die "cannot write a bee";
for (@text){
    print $TXT $_;
}

这段代码是未经测试编写的。你至少必须看看新线,那可能很乱。但你说“我什至不需要完整的解决方案,只需要一些能指引我正确方向的东西。” :-)

答案3

使用 perl 命令行选项的一种方法是,它们使其以准 awk 的方式运行。您可以在以下位置阅读它们perldoc perlrun

perl -F= -lane '
  @ARGV and %h=(%h,@F),next;
  print s|=\K.*|$h{$&}//$&|re; 
' fileA fileB

connect IP=192.192.2.3
connect port=5400

答案4

谢谢大家!我将尝试你的例子,这样我就可以学习我想到的替代方案(在我同事的帮助下):

系统 (“se​​d -is/'${var_one}'/'${var_two}'/g $outfile1”) ;

为了清楚起见, $var_one 和 $var_two 来自“将行分成两个变量”步骤。

再次感谢大家;

和平,克拉克“龙”威利斯

相关内容