【问题标题】:Perl; find and replace with special condition strings in multiple files珀尔;在多个文件中查找并替换为特殊条件字符串
【发布时间】:2020-08-21 06:56:39
【问题描述】:

我想寻求帮助,因为这超出了我的知识范围。我正在尝试在两个文件之间进行搜索和替换。到目前为止,我已经编写了一个将所有特定字符串 TerminationDate* 从文件一中隔离出来的代码。但是在另一个文件中搜索它的替换并返回位于其第一个匹配项下方 2 行的字符串对我来说是一个黑洞。

要处理的文件:

  1. 包含要通过搜索进一步处理的过滤数据 用于此文件中的字符串并从第二个文件中替换它们;
  2. 要从第一个文件中查找字符串的巨大文件;
  3. 仅包含从第一列中排序的第一个文件中过滤的字符串;

目标是从第二个文件替换第三个文件中的字符串,并用这些新数据重写第一个文件。例如,这个字符串 TerminationDate1 将被替换为文件 1 中的日期 2015/05/25。

第一个文件如下所示:

config vdom
edit vdom_1
config firewall policy
    edit 123
        set uuid xxxxxxxxxxxxxxx
        set srcintf "xxxxx"
        set dstintf "xxxxx"
        set srcaddr "xxxxx"
        set dstaddr "xxxxx"
        set action accept
        set schedule "TerminationDate1" <---
        set service "xxx"
        set logtraffic all
        set comments "xxxxx"
and so on

第二个文件的一部分是这样的:

config firewall schedule onetime
    edit "TerminationDate1"
        set start 12:01 2014/04/24
        set end 12:01 2015/05/25
        set color 0
        set expiration-days 4
and so on

以及我创建的最后一个作为临时的,到目前为止只包含一列过滤结果。也许第二列可以包含来自第二个文件的相应字符串。

TerminationDate1
TerminationDate2
TerminationDate3
and so on

【问题讨论】:

    标签: perl replace find


    【解决方案1】:

    您将此任务分解为几个步骤:

    1. 首先创建一个hash(例如%maps),它包含TerminationDate1date值的映射。在我的示例中,我使用正则表达式来提取信息,它应该比“阅读下面的 2 行”更好,因为您始终需要确保下面两行的内容是您需要的信息。检查的方法通常是正则表达式。
    2. 逐行浏览第一个文件并使用替换替换每一行的内容。由于您在第一步中获得了hash,因此您还需要在每一行中循环映射并尝试使用每个key 进行替换。
    3. 可选,您提到您有一个过滤列表,我在示例中没有使用它,如果需要,只需使用该列表来减少%maps 中的内容

    参考:https://perldoc.perl.org/perlre.html

    代码:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    
    my %maps;
    open my $in_2nd,'<', '2nd.txt' or die;
    my $name="";
    while (<$in_2nd>){
        chomp;
        if (/edit "(\w+)"/){
            $name=$1;
         }
         if (/set end (.*)$/){
            $maps{$name}=$1;
         }
    }
    close $in_2nd;
    warn(%maps); # check if the maps are correct
    
    open my $in_1st,'<', '1st.txt' or die;
    while(<$in_1st>){
        for my $k (keys %maps){
            s/$k/$maps{$k}/;
        }
        print;
    }
    close $in_1st;
    

    结果:

    config vdom
    edit vdom_1
    config firewall policy
        edit 123
            set uuid xxxxxxxxxxxxxxx
            set srcintf "xxxxx"
            set dstintf "xxxxx"
            set srcaddr "xxxxx"
            set dstaddr "xxxxx"
            set action accept
            set schedule "12:01 2015/05/25"
            set service "xxx"
            set logtraffic all
            set comments "xxxxx"
    

    【讨论】:

    • 您可以随时检查 %maps 以查看是否引入了额外的换行符并将其删除,或者您的原始文件是否存在格式问题。 @PeterMalik
    • OK 让它现在工作,修改了一行,如: if (/set end ..... (..\/..\/..).*/) .@Boying
    猜你喜欢
    • 2010-12-25
    • 2018-08-20
    • 1970-01-01
    • 2018-02-16
    • 2015-01-25
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    相关资源
    最近更新 更多