blackadder has asked for the wisdom of the Perl Monks concerning the following question:

O'Hello There

can someone give a clue on what is the best way to split a file such as this
vsan 1060 wwn 20:00:00:e0:69:41:26:e7 fcid 0x6d0d00 area dynamic vsan 1030 wwn 10:00:00:00:c9:28:29:44 fcid 0xa70001 dynamic vsan 1030 wwn 10:00:00:00:c9:28:2c:55 fcid 0xa70002 dynamic vsan 1060 wwn 50:06:0b:00:00:0b:3a:0e fcid 0x6d0e00 area dynamic vsan 1060 wwn 20:00:00:e0:69:41:3b:ca fcid 0x6d0f00 area dynamic vsan 1060 wwn 20:00:00:e0:69:40:d1:3f fcid 0x6d1000 area dynamic vsan 1060 wwn 20:00:00:e0:69:41:55:1f fcid 0x6d1100 area dynamic vsan 1060 wwn 20:00:00:e0:69:41:57:1e fcid 0x6d1200 area dynamic vsan 1060 wwn 10:00:00:00:c9:45:3a:21 fcid 0x6d0006 dynamic vsan 1060 wwn 20:00:00:e0:69:41:55:ff fcid 0x6d1300 area dynamic vsan 1050 wwn 50:06:0b:00:00:30:0d:f4 fcid 0x140100 area dynamic logging server 10.33.34.235 6 interface port-channel 1 switchport trunk allowed vsan 1000 switchport trunk allowed vsan add 1050 switchport description To CCC219 10.33.81.56 switchport mode E interface port-channel 3 switchport trunk allowed vsan 1000 switchport trunk allowed vsan add 1010 switchport trunk allowed vsan add 1050 switchport trunk allowed vsan add 1900 switchport description To CCC215 10.33.81.52 switchport mode E vsan database vsan 1050 interface port-channel 1 vsan 1060 interface fc1/3 vsan 1060 interface fc1/4 vsan 1060 interface fc1/8 vsan 1050 interface fc1/12 vsan 1060 interface fc1/14 vsan 1060 interface fc1/15 vsan 1010 interface fc1/16 vsan 1900 interface fc2/1 vsan 1060 interface fc2/3 vsan 1010 interface fc2/4 vsan 1050 interface fc2/7
to a format where I can obtain the;
interface port-channel {Number} = switchport description To {CCCswitch +_number, i.e either CCC215 or CCC219}
I tried splitting like so
if ($Info =~ /show running-config/) { my @array = (split /^\n+$/,$Info); #for my $stuff (@array) #{ #print "$stuff\n"; #} #$var1= $1, next if (/(interface port-channel \d+)$/); print "$array[1]\n"; } }
But what I got was the whole log file as one array element!

I can't see how can I split the damn thing wat all!...Any Help please.

Thanks

Blackadder ############ UPDATE ###############

I am trying this now,...Not sure if its going to work.
my ($var1, $var2); if ($Info =~ /show running-config/) { $var1 = $1, next if (/(interface port-channel \d+)$/); $var2->{$var1}->{$1} = $2 if (m|(description to CCC\d+/\d+)\s+\[(\w+)\ +]|); print "::$1\n"; }
I didn't get any out put this time...Himmmmmmmm!!!

Replies are listed 'Best First'.
Re: Another Challenge: Splitting data into chunks part2
by goldclaw (Scribe) on Sep 21, 2005 at 15:16 UTC
    If you have all of that text in $Info, then this would do what you want I think:
    my %interface_to_desc= ($Info=~/interface\s+port-channel\s+(\d+).*?switchport\s+description\s ++To\s+(\S+)\s+/gs);
    The hash interface_to_desc will then have the port-channel number as keys, and the text after description To as values.

    Hope that helps. Oh, and have a look in the perlop manpage for how the g and s switch to regular expression works. Thats the whole secret here:-)

    gc

      Nice! (A ++ just wasn't enough.)
Re: Another Challenge: Splitting data into chunks part2
by kwaping (Priest) on Sep 21, 2005 at 15:14 UTC
    I'm not exactly sure of your desired output format, but how's this:
    #!/usr/bin/perl use warnings; use strict; use Data::Dumper::Simple; my ($hash,$key); while(<DATA>) { $key = $1, next if (/interface port-channel (\d+)$/); $hash->{$key}->{$1} = $2 if (/switchport description To (\w+) ([\d +\.]+)/); } print Dumper($hash); __DATA__ vsan 1060 wwn 20:00:00:e0:69:41:26:e7 fcid 0x6d0d00 area dynamic vsan 1030 wwn 10:00:00:00:c9:28:29:44 fcid 0xa70001 dynamic vsan 1030 wwn 10:00:00:00:c9:28:2c:55 fcid 0xa70002 dynamic vsan 1060 wwn 50:06:0b:00:00:0b:3a:0e fcid 0x6d0e00 area dynamic vsan 1060 wwn 20:00:00:e0:69:41:3b:ca fcid 0x6d0f00 area dynamic vsan 1060 wwn 20:00:00:e0:69:40:d1:3f fcid 0x6d1000 area dynamic vsan 1060 wwn 20:00:00:e0:69:41:55:1f fcid 0x6d1100 area dynamic vsan 1060 wwn 20:00:00:e0:69:41:57:1e fcid 0x6d1200 area dynamic vsan 1060 wwn 10:00:00:00:c9:45:3a:21 fcid 0x6d0006 dynamic vsan 1060 wwn 20:00:00:e0:69:41:55:ff fcid 0x6d1300 area dynamic vsan 1050 wwn 50:06:0b:00:00:30:0d:f4 fcid 0x140100 area dynamic logging server 10.33.34.235 6 interface port-channel 1 switchport trunk allowed vsan 1000 switchport trunk allowed vsan add 1050 switchport description To CCC219 10.33.81.56 switchport mode E interface port-channel 3 switchport trunk allowed vsan 1000 switchport trunk allowed vsan add 1010 switchport trunk allowed vsan add 1050 switchport trunk allowed vsan add 1900 switchport description To CCC215 10.33.81.52 switchport mode E vsan database vsan 1050 interface port-channel 1 vsan 1060 interface fc1/3 vsan 1060 interface fc1/4 vsan 1060 interface fc1/8 vsan 1050 interface fc1/12 vsan 1060 interface fc1/14 vsan 1060 interface fc1/15 vsan 1010 interface fc1/16 vsan 1900 interface fc2/1 vsan 1060 interface fc2/3 vsan 1010 interface fc2/4 vsan 1050 interface fc2/7

    Output:
    $hash = { '1' => { 'CCC219' => '10.33.81.56' }, '3' => { 'CCC215' => '10.33.81.52' } };
      Yes, I have posted the wrong code!!!! It really has been very long day/night.

      Your code works, but how can I combine 2 loops into one? What I mean is this
      #! c:/perl/bin/perl.exe use strict; my ($Rec2, $pc_name); my ($hash,$key); open (LST,"c:/showtech".$ARGV[0].".txt") || die "$!\n"; while(<LST>) { $key = $1, next if (/interface port-channel (\d+)$/); $hash->{$key}->{$1} = $2 if (/switchport description To (\w+) ([\d +\.]+)/); } close LST; open (LST,"c:/showtech".$ARGV[0].".txt") || die "$!\n"; while(<LST>) { $pc_name = $1, next if (/(port-channel \d+)$/); $Rec2->{$pc_name}->{$1} = $2 if (m|(fc\d+/\d+)\s+\[(\w+)\]|); } for my $data (keys %{$Rec2}) { print "\n$data \n"; } for my $data (keys %{$hash}) { print "$data\n"; }
      I am sure I don't have to open the file twice. but not sure on how to do it. If I merge both loops then only one loop works!
      Blackadder
        If you change your loop to something like this is should work:
        my $iname; while(<LST>) { $iname=$1, next if /port-channel (\d+)/; next if !defined $iname; $hash->{$iname}->{$1} = $2 if (/switchport description To (\w+) ([\d\.]+)/); $Rec2->{$iname}->{$1} = $2 if (m|(fc\d+/\d+)\s+\[(\w+)\]|); }
        Note, there is one small difference with the results you got from your code. Im sure you can see it, and fix it if its important:-)

        gc

Re: Another Challenge: Splitting data into chunks part2
by InfiniteSilence (Curate) on Sep 21, 2005 at 15:07 UTC
    blackadder, I don't get this post. Your code line:

    while(<DATA>){ #I asssumed this $Info = $_; #this also my ($var1, $var2); if ($Info =~ /show running-config/)

    Doesn't match anything in your dataset. Did you post the wrong dataset? I do not see the literal words 'show running-config' anywhere in the data you posted. Is it supposed to be a command with backticks (e.g. `show running-config`)?

    Celebrate Intellectual Diversity