forked from AkshayAgarwal007/Jekyll-Mono
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path2008-04-23-una-implementazione-di-cercavert-in.html
21 lines (16 loc) · 6.53 KB
/
2008-04-23-una-implementazione-di-cercavert-in.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
---
layout: post
title: Una implementazione di cercaVert in Perl
date: '2008-04-23T08:07:00.001+02:00'
author: Luca Ferrari
tags:
- linux
- perl
- università
modified_time: '2008-04-23T08:21:00.124+02:00'
blogger_id: tag:blogger.com,1999:blog-1836481905487384887.post-4590581938498133802
blogger_orig_url: http://fluca1978.blogspot.com/2008/04/una-implementazione-di-cercavert-in.html
permalink: /:year/:month/:day/:title.html
---
<h1>~</h1>
In questo articolo presento un semplice script Perl che realizza la funzione cercaVert di Excel operando su un file CSV. L'idea è quella di fornire allo script un file CSV specificandogli di cercare i valori di una colonna in un'altra, e di riportare in un file di uscita i valori che trovano riscontro fra le due colonne.<br />In altre parole, se il file CSV contiene i seguenti dati di esempio:<br /><br /><span style="font-style: italic;">luca;marco;maschio;</span><br /><span style="font-style: italic;">marco;lucia;femmina;</span><br /><span style="font-style: italic;">simone;luca;maschio;</span><br /><br /><br />e si specifica di cercare i valori della seconda colonna nella prima, allora si avrà match sui valori <span style="font-style: italic;">marco</span> (riportato nella prima riga, seconda colonna - seconda riga, prima colonna) e <span style="font-style: italic;">luca</span> (riportato nella terza riga, seconda colonna - prima riga, prima colonna), ottenendo in uscita il file:<br /><br /><span style="font-style: italic;">marco;1;<br />luca;1;</span><br /><br />dove la prima colonna rappresenta il valore cercato e la seconda il numero di occorrenze di tale valore nella prima colonna.<br /><br />Il funzionamento dello script è abbastanza semplice: oltre al file CSV da analizzare vengono passati come argomenti i numeri delle colonne sulle quali fare match, partendo da 1 per la prima colonna a sinistra. Il programma legge riga per riga il file CSV memorizzando in un hash (<span style="font-style: italic;">occurences</span>) il valore cercato e il relativo numero di occorrenze, che al momento risulta pari a zero. Allo stesso tempo, viene memorizzato in un array (<span style="font-style: italic;">domain</span>) la lista dei valori in cui cercare. In altre parole, se si vuole controllare la colonna 2 sulla colonna 1, allora <span style="font-style: italic;">occurences</span> conterrà tutti i valori della colonna 2, mentre <span style="font-style: italic;">domain</span> i valori della colonna 1. Terminata la lettura del file, e quindi con le due origini dati in memoria, viene fatto un ciclo su tutti i valori memorizzati nell'hash e li si confronta con tutti i valori (che possono essere duplicati) del dominio in cui cercare, incrementando le eventuali occorrenze. Infine si riportano sul file di uscita le chiavi e il numero di occorrenze trovate.<br /><br /><pre>#!/usr/bin/perl<br /><br /># Programma che emula la funzione cercavert di excel: ricerca un campo di una colonna di un file CSV<br /># in un'altra colonna.<br />#<br /># Argomenti dello script:<br /># $ARGV[0] = nome del file CSV da leggere (deve essere<br /># formattato con separatori ';'<br /># $ARGV[1] = numero della colonna da cui prendere i codici<br /># $ARGV[2] = numero della colonna in cui cercare i codici<br />#<br /># Ad esempio:<br />#<br /># cercaVert.pl file.csv 2 1<br />#<br /># ricerca i codici della colonna 2 nella colonna 1 del file file.csv<br /><br /><br /># * Copyright (C) Luca Ferrari 2008<br /># *<br /># * This program is free software: you can redistribute it and/or modify<br /># * it under the terms of the GNU General Public License as published by<br /># * the Free Software Foundation, either version 3 of the License, or<br /># * (at your option) any later version.<br /># *<br /># * This program is distributed in the hope that it will be useful,<br /># * but WITHOUT ANY WARRANTY; without even the implied warranty of<br /># * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br /># * GNU General Public License for more details.<br /># *<br /># * You should have received a copy of the GNU General Public License<br /># * along with this program. If not, see <http://www.gnu.org/licenses/>.<br /><br /><br /><br /># controllo numero argomenti<br />if( $#ARGV < 3 ){<br /> print "\nUtilizzo: $0 <nome_file_csv> <numero_colonna_sorgente> <numero_colonna_destinazione> <file_output>\n";<br /> exit(0);<br />}<br /><br /><br /># apro il file da cui leggere e su cui scrivere<br />open(FILE_CSV, "<$ARGV[0]") || die("\nImpossibile aprire il file $ARGV[0]\n$!\n");<br />open(FILE_OUT,">$ARGV[3]") || die("\nImpossibile aprire il file $ARGV[3]\n$!\n");<br />print FILE_OUT "Valore ricercato (colonna $ARGV[1]); numero di occorrenze trovate nella colonna $ARGV[2];\n";<br />$SRC_COLUMN = $ARGV[1] - 1;<br />$DST_COLUMN = $ARGV[2] - 1;<br />print "\nRicerco le occorrenze dei valori della colonna $DST_COLUMN nella colonna $SRC_COLUMN del file $ARGV[0]...\n";<br /><br /><br /># leggo il file una volta, estrando la colonna sorgente e<br /># costruisco un hash che contiene tutte le occorrenze trovate, e un<br /># array che contiene tutti i valori in cui cercare successivamente<br />$occurences = {};<br />@domain = ();<br /><br />while( $line = <file_csv> ){<br /> @parts = split(";", $line);<br /> <br /> $srcValue = $parts[ $SRC_COLUMN ];<br /> $dstValue = $parts[ $DST_COLUMN ];<br /> <br /> # memorizzo il valore nell'hash<br /> $occurences->{ $srcValue } = 0;<br /><br /> # aggiungo il valore in cui cercare nell'array<br /> $domain[ ++$#domain ] = $dstValue;<br />} # fine del ciclo while<br /><br /><br />close(FILE_CSV);<br /><br />print "\nInizio ricerca fra $#domain valori...\n";<br />@domain = sort(@domain);<br />$counter = 0;<br /><br />foreach $chiave (sort(keys(%$occurences))){<br /> foreach $valore (@domain){<br /> if( $valore eq $chiave ){<br /> $occurences->{$chiave} += 1;<br /> $counter ++;<br /> }<br /> }<br />}<br /><br />print "\nTrovati $counter valori uguali...";<br /><br /># produco in uscita il risultato<br />foreach $chiave (sort(keys(%$occurences))){<br /> if( defined($occurences->{$chiave}) && $occurences->{$chiave} > 0 ){<br /> print FILE_OUT "\n$chiave;" . $occurences->{$chiave};<br /> }<br />}<br /><br /><br />print "\nfinito\n";<br /></pre><br />Lo script è piuttosto semplice, e l'utilizzo di un hash e di un array consente di tenere solo i valori non duplicati da cercare contro un dominio di valori che possono essere duplicati. Va notato che, tenendo le fonti dati in memoria, in caso di file CSV molto grandi questo script tenderà a consumare notevoli risorse.