GeorgMN has asked for the wisdom of the Perl Monks concerning the following question:
Hello monks,
First off. I searched the archives here. What i found did not really compute (in my head at least), or was too far removed from what i need to accomplish.
Here is the surrounding criteria. My goal is to take several values from a file, line by line. The items in these lines have an important relation to one another that needs to be kept intact. I then need to compare some of these elements and compare them to elements from another file. If some the values on a given line match (MAC address in my case), i need to splice the lines from both files together. The match between the two files is the scalar "$mac".
From what i read so far I should be using a hash reference for this. My problem: I am not a programmer and i am not sure how to use hashes correctly. I cannot seem to push the scalars into the hash.
my $ERRORCOUNT=0; my %HASH; my %OTHERHASH; ... foreach my $LINE (@LINES) { # the sub-routine works and is returning the desired output my ($vlan, $mac, $int, $counter) = linesifter($LINE); if ($error eq 1) { ERRORCOUNT++; } else { my @VLANS, @MACS, @INTS); push $HASH{$MACS[$mac]}, [$VLANS[$vlan], [$INTS[$int]]; } # here will follow similar code from another file # compare $HASH[$MACS[keymatch]] to $OTHERHASH[$MACS[$keymatch]] # then do *magic* and line up all items that are referenced by matchin +g MAC key in both files onto one line. Store in a file. sub linesifter { #... #...omitted # various regex'es for grep'ing data #... return ($vlan, $mac, $int, $error); }
I am sure i got the hash declarations wrong. Any input on how i can compare to hashes or arrays or lines within each to one another and interpolate the data is very welcomed. Thank you as always.
#!/usr/bin/perl # # use strict; use warnings; use File::Glob ':globally'; my @SHOW_ARP = <~/Documents/show_outputs/*arp*.txt>; my @SHOW_MAC = <~/Documents/show_outputs/*mac*.txt>; #my $CLEAN_ARP_REC = '~/Documents/clean_arp.tmp'; #my $CLEAN_MAC_REC = '~/Documents/clean_mac.tmp'; my $CLEAN_ARP_REC = '/home/gtreptow/Documents/show_outputs/clean_arp.t +mp'; open (OUTPUT, "> $CLEAN_ARP_REC") or die "Could not open $CLEAN_ARP_RE +C."; # my global hash that should contain all my matches #my %ARP_HASH = (); my %MAC_HASH; my (@VLANS, @MACS, @INTS); foreach my $FILES (@SHOW_MAC) { open (INFILE, '<', $FILES); print "using file: $FILES\n"; my $FAILCOUNTER = 0; my $COUNTER = 0; chomp (my @LINES = <INFILE>); foreach my $LINE (@LINES) { my ($VLAN, $MAC, $INT, $COUNTER) = &mac_linesifter($LINE); + # Call sub-routine "linesifter" and pass every line to it if ($COUNTER eq 1) { $FAILCOUNTER++; #print "Saw an INCOMPLETE\n"; # Test each l +ine } else { #print "$VLAN \t $MAC \t $INT \t $COUNTER \n"; #$MAC_HASH = {}; #$MAC_HASH->{MAC}= "$MAC"; #$MAC_HASH->{VLAN}="$VLAN"; #$MAC_HASH->{INT}="$INT"; my ($VLANS, @MACS, @INTS); push @{ $MAC_HASH{$MACS[$MAC]} }, [$VLANS[$VLAN] ,$INTS[$I +NT]]; } } # we also need to get the hostname print "!!! $FAILCOUNTER ARP records ignored due to incomplete entries +!!!\n"; print "\n"; print "Contents of Hash ARP_HASH:\n"; foreach my $VALUE (sort keys %MAC_HASH) { print "$VALUE, $ARP_HASH{$VALUE}[0],$ARP_HASH{$VALUE}[1],$ARP_HASH +{$VALUE}[2]\n"; } } close (OUTPUT); ### BEGIN SUB-ROUTINE 2 ### sub mac_linesifter { my ($LINE) = @_; my $VLAN; my $MAC; my $INT; my $COUNTER = 0; if ($LINE !~ m/^\*/) # skip if line d +oes not start with "*" { $COUNTER=1; no warnings "exiting"; next; } if ($LINE =~ m/^\s*$/) # skip empty lin +es { $COUNTER=1; no warnings "exiting"; next; } if ($LINE =~ m/static/) # skip static entri +es { $COUNTER=1; no warnings "exiting"; next; } if ($LINE =~ m/(^\*\ [0-9]*)/) # match VLAN + identifier { # remove leading "* " $VLAN = substr($1,2); } if ($LINE =~ m/([0-9a-f]{4}\.[0-9a-f]{4}\.[0-9a-f]{4})/) + # match MAC { $MAC = $1; } # match either - example Eth101/0/48", Eth12/1, Po12 - add regex h +ere for additional interace type matches if ($LINE =~ m/([A-Z]{1}[a-z]{2}[0-9]*\/[0-9]*\/[0-9]*|[A-Z]{1}[a- +z]{2}[0-9]*|[Po]{2}[0-9]{2})/) { $INT = $1; #print "int match: $1\n"; } return ($VLAN, $MAC, $INT, $COUNTER); # return +these values from sub-routine } ### END SUB-ROUTINE 2 ###
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Merging hashes at key match
by Anonymous Monk on Mar 22, 2016 at 15:12 UTC | |
by GeorgMN (Acolyte) on Mar 22, 2016 at 15:19 UTC | |
by Your Mother (Archbishop) on Mar 22, 2016 at 15:55 UTC | |
|
Re: Merging hashes at key match
by FreeBeerReekingMonk (Deacon) on Mar 22, 2016 at 20:52 UTC | |
by GeorgMN (Acolyte) on Mar 23, 2016 at 08:48 UTC | |
by GeorgMN (Acolyte) on Mar 23, 2016 at 14:19 UTC | |
by FreeBeerReekingMonk (Deacon) on Mar 24, 2016 at 00:09 UTC |