0

I would like to ask for help as this is beyond my knowledge. I`m trying to do a search and replace between 2 files. So far I have written a code that isolates all specific strings TerminationDate* from file one. But to search for its replacement in another file and return the string located 2 lines below its first match is a black hole for me.

Files to work with:

  1. containing filtered data to be processed further by searching for strings within this file and replace them from the 2nd file;
  2. huge file to be looked for the strings from the 1st file;
  3. containing the filtered strings only from the 1st file sorted in one column;

Goal is to have strings from the 3rd file replaced from the 2nd one and rewrite the 1st file with these new data. So for example this string TerminationDate1 will be replaced with the date 2015/05/25 in file 1.

The first file looks like this:

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

part of the 2nd file like this:

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

and the last one I have created as temporary one containing so far jut one column with filtered results. Maybe the 2nd column could contain corresponding strings from the 2nd file.

TerminationDate1
TerminationDate2
TerminationDate3
and so on

1 Answer 1

1

You break this task to a few steps:

  1. Make a hash (%maps in example) first, it contains the mapping for TerminationDate1 to the date value. In my example I've used regular expression to extract the info, it should be better than "read 2 lines below", as you always need to make sure the content on two lines below is the info you need. The method to check is usually the regular expression.
  2. Go through the first file line by line and use substitute to replace the content on each line. Since you've got a hash in the first step, you also need to loop the map in each line and try the substitute using each key.
  3. Optionally, you mentioned you've got a filtered list, I don't use it in the example, if needed, just use the list to reduced the content in the %maps

Reference: https://perldoc.perl.org/perlre.html

Code:

#!/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;

Result:

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"
Sign up to request clarification or add additional context in comments.

2 Comments

you could always check the %maps to see if there are extra newline introduced and remove them, or if your original file has format issue. @PeterMalik
OK got it working now, modified one line like: if (/set end ..... (....\/..\/..).*/) .@Boying

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.