Объединение нескольких строк в одну и взлом содержимого - PullRequest
0 голосов
/ 08 марта 2012

Это конфигурация, которая у меня есть, и я пытаюсь объединить ее в одну команду маршрута, которую я могу вставить в Cisco ASA.

set device "internal"
set dst 13.13.13.13 255.255.255.255
set gateway 172.16.1.1

set device "internal"
set dst 14.14.14.14 255.255.255.255
set gateway 172.16.1.1

set device "internal"
set dst 15.15.15.15 255.255.255.255
set gateway 172.16.1.1

Присоедините ее к одному устройству, затем изменитесоответственно, чтобы в итоге выглядело что-то вроде этого

route internal 13.13.13.13 255.255.255.255 172.161.1.1

, остальные 3 строки могут исчезнуть.

Я бы хотел сделать это на Perl, так как я пишу другие сценарии дляделать другие части исходной конфигурации

Ответы [ 3 ]

0 голосов
/ 08 марта 2012

Если ваш файл конфигурации состоит из «абзацев» (разделов), разделенных пустыми строками, как предполагает ваш ввод, вы можете сделать:

#!/usr/bin/env perl
use strict;
use warnings;
local $/ = ""; #...paragraph mode...
while (<>) {
    chomp;
    m{^set.+"internal".+dst\s*([\d\.\s]+$).+gateway\s*(.+)$}ms and
        print "route internal $1 $2\n";
}
0 голосов
/ 08 марта 2012

Быстрый взлом. Это будет считывать набор значений (разделенных двумя последовательными символами новой строки), помещать его в хеш, а затем помещать этот хеш в массив. Использование входного разделителя записей $/ для чтения записей. Установка $/ в "" пустая строка похожа на установку "\n\n", подробнее читайте в документации, приведенной выше.

Не совсем уверен, что вам нужно здесь. Если объединена только одна строка, просто сохраните хеш, не помещая его в массив. Он «запомнит» первую запись.

use strict;
use warnings;

$/ = "";   # paragraph mode
my @sets;
while (<DATA>) {
    my %set;
    chomp;               # this actually removes "\n\n" -- the value of $/
    for (split /\n/) {   # split each record into lines
        my ($set,$what,$value) = split ' ', $_, 3;  # max 3 fields
        $set{$what} //= $value;        # //= means do not overwrite
    }
    $set{device} =~ s/^"|"$//g;        # remove quotes
    push @sets, \%set;
}

for my $set (@sets) {  # each $set is a hash ref
    my $string = join " ", "route", 
        @{$set}{"device","dst","gateway"};  # using hash slice
    print "$string\n";
}

__DATA__
set device "internal"
set dst 13.13.13.13 255.255.255.255
set gateway 172.16.1.1

set device "internal"
set dst 14.14.14.14 255.255.255.255
set gateway 172.16.1.1

set device "internal"
set dst 15.15.15.15 255.255.255.255
set gateway 172.16.1.1

Выход:

route internal 13.13.13.13 255.255.255.255 172.16.1.1
route internal 14.14.14.14 255.255.255.255 172.16.1.1
route internal 15.15.15.15 255.255.255.255 172.16.1.1
0 голосов
/ 08 марта 2012

Предполагая, что ваш заказ всегда device, dst, gateway, тогда это работает:

use strict;
use warnings;


my @devices=(); #Array to store device strings
my $current_device=""; #String to capture current device.

while(<DATA>)
{
    chomp;
    if(/^set (\w+) (.+)$/)
    {
        if($1 eq "device")
        {
            $current_device="route $2";
            $current_device=~s/"//g;
        }
        elsif($1 eq "dst")
        {
            $current_device.=" $2";
        }
        elsif($1 eq "gateway")
        {
            $current_device.=" $2";
            push @devices,$current_device;
        }
    }
}

print "$_\n" foreach(@devices);




__DATA__
set device "internal"
set dst 13.13.13.13 255.255.255.255
set gateway 172.16.1.1

set device "internal"
set dst 14.14.14.14 255.255.255.255
set gateway 172.16.1.1

set device "internal"
set dst 15.15.15.15 255.255.255.255
set gateway 172.16.1.1

Вывод:

route internal 13.13.13.13 255.255.255.255 172.16.1.1
route internal 14.14.14.14 255.255.255.255 172.16.1.1
route internal 15.15.15.15 255.255.255.255 172.16.1.1
...