比较CSV文件中的值 [英] Compare values in csv files

查看:119
本文介绍了比较CSV文件中的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在比较两个csv文件中的不同值.如果没有匹配项,我想在管理系统中添加(或更新)设备.

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(名称,ip)-主系统

 Test1, 10.56.7.13
 Test2, 10.56.4.14
 Test3, 10.56.5.15

output2.csv(id,名称,ip)-辅助系统

 1234,Test1, 10.56.7.13
 1235,Test2, 10.56.4.10

我的结果应该是:我对Test1不执行任何操作(因为它已经在系统2中),我应该更新Test2(因为现在我有一个不同的IP地址),并且应该添加Test3,因为我在辅助系统中没有它.

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;

此行if ( $first{$name_first} e.g. $first{$name_second}出现错误.我认为我的比较是错误的-有更好的方法吗?

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?

一个问题:对于UPDATE(PUT请求),我需要单独的键.因为我需要在URL中放入id,并且需要放入XML template nameipaddress,所以应该添加.我可以这样吗?

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";

推荐答案

对于所描述的任务,您需要将第二个文件的每一行与第一个文件中的所有name-ip进行比较,从而与其所有行进行比较.一种有效的方法是首先为每个文件构建哈希.

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.

请注意,将模块用于CSV 会更好,例如此帖子中的答案. 我将您的方法放在下面,仅着眼于实际处理.

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.

use strict;
use warnings;
use feature qw(say);

my ($file_1, $file_2) = ('output1.csv', 'output2.csv');

open my $fh, '<', $file_1  or die "Can't open $file_1: $!";
my %first = map { chomp; split /\s*,\s*/ } <$fh>;            #/

open    $fh, '<', $file_2  or die "Can't open $file_2: $!";
my %second = map { chomp; (split /\s*,\s*/)[1,2] } <$fh>;
close $fh;

foreach my $name (sort keys %first) {
    if (not exists $second{$name}) {
        say "Devices should be added: $name";
        next;
    }

    if ($first{$name} eq $second{$name}) {
        say "Match found $name, $first{$name}";
    }
    else {
        say "UPDATE need be done for $second{$name}"
    }   
}   

此打印


Match found Test1, 10.56.7.13
UPDATE need be done for 10.56.4.10
Devices should be added: Test3

评论

  • 我将文件命名更改为词法变量,因为我看不到为此使用constant的意义

我使用一个文件句柄,该文件句柄在重新打开(对于第二个文件)时会关闭

I use one filehandle, which gets closed when reopened (for the second file)

每行为split时,返回的对直接分配散列.如果您需要更多处理(可能是第二个文件的'id')或输入检查变为显式循环.以这种方式分配哈希值时,还假设使用唯一的名称(名称仅显示在一行上).

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.

这篇关于比较CSV文件中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆