I am comparing different values in two csv files. If I do not have a match, I want to add (or update) my devices in my Management System.
output1.csv (name, ip) - Primary system
Test1, 10.56.7.13
Test2, 10.56.4.14
Test3, 10.56.5.15
output2.csv (id,name,ip) - Secondary system
1234,Test1, 10.56.7.13
1235,Test2, 10.56.4.10
My result should be: I do nothing with Test1
(because it is already in System 2), I should update Test2
(because now I have a different ip address) and I should add Test3
, because I do not have it in the secondary System.
use strict;
use warnings;
use feature qw(say);
use autodie;
use constant {
FILE_1 => "output1.csv",
FILE_2 => "output2.csv",
};
my %first;
my $name_first;
my $ip_first;
open my $output_1, "<", FILE_1;
while ( <$output_1> ) {
chomp;
($name_first, $ip_first) = split /,/; #/
$first{$name_first}=1;
$first{$ip_first}=1;
}
close $output_1;
my %second;
open my $output_2, "<", FILE_2;
while ( <$output_2> ) {
chomp;
my ($id_second,$name_second,$ip_second) = split /,/;
if ( $first{$name_first} && $first{$ip_second} ) {
print "Match found $name_second, $ip_second\n";
if ( $first{$name_first} eq $first{$name_second} &&
$first{$ip_first} ne $first{$ip_second})
{
print "It should be done UPDATE for $name_second\n";
else
print "Devices should be added: $name_first\n"
$second{$name_second}++;
}
}
}
close $output_2;
I am getting an error at this line if ( $first{$name_first} e.g. $first{$name_second}
. I think my compare is wrong - is there a better way of doing it?
One question more: for UPDATE (PUT Request) I need separate keys. Because i need my id
in URL
and I need to put in XML template
name
and ipaddress
, that should be added. May I do it this way?
else {
say "UPDATE need be done for $second{$name}";
my $xml = XML::Twig -> new -> parsefile ( 'template.xml' );
$xml ->set_pretty_print('indented_a');
open ( my $input, '<', 'output2.csv' ) or die $!;
while ( <$input> ) {
chomp;
my $id, my $name, $second{$name} = split /,/;
$xml -> root -> set_att('name', $name );
$xml -> get_xpath('//ipaddress',0) -> set_text($second{$name});
my $uri="https://hostname:9060/ers/config/networkdevice/$id";
For the described task you need to compare each line of the second file with all name-ip in the first file, thus with all its lines. An efficient way of doing this is to first build hashes for each file.
Please note that it is much better to use a module for CSV, like Text::CSV, than to do it by hand; there's much chance for trouble otherwise. See answers in this post, for example. I keep your approach below merely so to focus on the actual processing.
This prints
Comments
I've changed file naming to lexical variables as I don't see a point in using
constant
for thisI use one filehandle, which gets closed when reopened (for the second file)
A hash is assigned directly by pairs returned when each line is
split
. If you need more processing (perhaps 'id' for the second file) or checking of input change to an explicit loop. Assigning a hash this way also assumes unique names (names appear on only one line).This assumes that files aren't huge as they are both read first
The code in the question is completely broken, with basic syntax errors. Always clean up your code before concluding that it fails. If this is a matter of posting please do your best with what you post.