2012-03-07 42 views
-1

这是我的配置,我试图将其合并为一条可以粘贴到思科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,因为我正在写其他脚本来完成源配置

+0

我认为它要在你的输出,'172.161.1.1'当你输入接近的唯一的事情就是'172.16.1.1'一个错字? – TLP 2012-03-07 23:18:20

+0

你是对的,错字,对不起, – PhobicSTI 2012-03-07 23:19:11

+0

你是否希望使用第一个出现的“dst”,也就是'13.13.13.13',或者你有其他的方法来选择你的输出? – TLP 2012-03-07 23:21:05

回答

0

的其他部分假设您的订单总是devicedstgateway那么这个工程:

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 
+0

这工作真棒,我怎么会砍掉这个约一英寸左右,输入为源文件,输出为目标文件。 – PhobicSTI 2012-03-07 23:51:26

+0

你可以a)从源文件和输出文件中['打开'](http://perldoc.perl.org/functions/open.html)文件句柄,读取前者并写入后者,或者b)从'STDIN'中读取脚本并从命令行重定向,例如'perl my_script.pl output_file'。 – 2012-03-08 00:08:24

+0

谢谢杰克,这很好。 – PhobicSTI 2012-03-08 02:09:25

0

如果您的配置文件由 “段”(节的s)按照您的输入建议用空行分隔,您可能会这样做:

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

似乎不适合我。我添加了这个'open SRCFILE,“<”,$ ARGV [0]或者$! 打开DSTFILE,“>”,$ ARGV [1]或者死掉$!;' – PhobicSTI 2012-03-07 23:42:57

+0

@PhobicSTI - FYI,[bareword filehandles bad](http://stackoverflow.com/questions/1479741/why-is-three-argument-open-calls-with-lexical-filehandles-a-perl-best -实践)。 – 2012-03-08 00:25:26

+0

@PhobicSTI - 因为每个命令行参数被假定为一个文件名,所以不需要显式的'open'。正如我所说的,这假设你的配置文件由用空或空白行分隔的段落组成。 – JRFerguson 2012-03-08 13:07:20

0

快速入侵。这将读取一组值(由两个连续的换行符分隔),将其放入散列中,然后将该散列推送到数组上。使用输入记录分隔符$/来读取记录。将$/设置为""空字符串有点像将其设置为"\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