Perl; найти и заменить специальными строками условий в нескольких файлах - PullRequest
0 голосов
/ 06 мая 2020

Я хотел бы попросить о помощи, так как это мне неизвестно. Я пытаюсь выполнить поиск и заменить 2 файла. Пока что я написал код, который изолирует все указанные c строки TerminationDate * от первого файла. Но искать его замену в другом файле и возвращать строку, расположенную на 2 строки ниже первого совпадения, для меня - черная дыра.

Файлы, с которыми нужно работать:

  1. содержащие отфильтрованные данные для дальнейшей обработки путем поиска строк в этом файле и замены их из 2-го файла;
  2. огромный файл для поиска строк из 1-го файла;
  3. содержащий отфильтрованные строки только из 1-й файл, отсортированный в один столбец;

Цель состоит в том, чтобы строки из 3-го файла были заменены из 2-го и перезаписали 1-й файл с этими новыми данными. Так, например, эта строка TerminationDate1 будет заменена датой 2015/05/25 в файле 1.

Первый файл выглядит так:

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

часть 2-го файла, как это :

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

1 Ответ

1 голос
/ 06 мая 2020

Вы разбиваете эту задачу на несколько шагов:

  1. Сначала создайте hash (%maps в примере), он содержит сопоставление TerminationDate1 со значением date. В моем примере я использовал регулярное выражение для извлечения информации, это должно быть лучше, чем «прочитать две строки ниже», так как вам всегда нужно убедиться, что содержимое в двух строках ниже является необходимой вам информацией. Метод для проверки обычно представляет собой регулярное выражение.
  2. Go через первый файл построчно и используйте замену для замены содержимого в каждой строке. Поскольку на первом этапе у вас есть hash, вам также необходимо l oop карту в каждой строке и попробовать замену, используя каждый 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"
...