Rechercher : dans
Par :

[Perl] souci lecture fichier csv

Dernière réponse le 1 fév 2007 à 14:34:11 Vince17, le 23 jan 2007 à 21:01:55 
 Signaler ce message aux modérateurs

Bonjour à tous,
Sur fedora j'ai créer un serveur dns avec reverse il m'a été demandé avec un script perl de pouvoir générer un fichier csv (ou es noté hote + ip de type toto;10.3.2.141)
Mon script ne me permet pas de passer à la ligne suivante du fichier et la je suis perdu. Il arrive bien à calculé le nombre de ligne mais il m'affiche x fois la dernière ligne de mon fichier csv.
Pouvez vous m'indiquer une solution afin qu'il affiche toutes les lignes dans mon fichier dns
Merci d'avance

P.S: Si ca peut être utile je vous affiche mon script en perl

#!/usr/bin/perl

($toto, $ent) = @ARGV;

open DB, ">/var/named/toto.fr";
open REV, ">/var/named/10.in-addr.arpa.rev";

$j = 0;
open ADRIP, "tableip.csv";
while(<ADRIP>)
{
if($j == 0)
{
($hote,$IP) = split /;/, <ADRIP>;
}
else
{
$nom[$j] = ($hote,$IP);
}
$j++;
}

#($hote,$IP) = split /;/, <ADRIP>;
close ADRIP;

print DB
"\$\TTL\t86400\n",
"@\tIN\tSOA\t ent.toto.fr. root.toto.fr. (\n",
"\t\t\t\t1997022700\t; Serial\n",
"\t\t\t\t28800\t; Refresh\n",
"\t\t\t\t14400\t; Retry\n",
"\t\t\t\t3600000\t; Expire\n",
"\t\t\t\t86400 )\t; Minimum\n",
"\n",
"@\tIN\tNS\tent.toto.fr\n",
"ent\tIN\tA\t10.2.2.145\n",
"test\tIN\tCNAME\tent\n";

print REV
"\$\TTL\t86400\n",
"@\tIN\tSOA\tent.toto.fr. root.toto.fr. (\n",
"\t\t\t\t1997022700\t; Serial\n",
"\t\t\t\t28800\t; Refresh\n",
"\t\t\t\t14400\t; Retry\n",
"\t\t\t\t3600000\t; Expire\n",
"\t\t\t\t86400 )\t; Minimum\n",
";\n",
"@\tIN\tNS\tent.toto.fr.\n",
"1\tIN\tPTR\tent.toto.fr.\n";

foreach $tablip (1 .. $j) {
print DB "$hote\tIN\tA\t$IP\n";
print REV "$IP\tIN\tPTR\t$hote\n";
}


close DEB; close REV;

Configuration: Windows XP
Firefox 1.5.0.9

Meilleures réponses pour « [Perl] souci lecture fichier csv » dans :
[Python] Lire et écrire des fichiers CSV VoirLIRE ET ÉCRIRE DES FICHIERS CSV Python www.python.org, dans sa version 2.4 supporte de facto le format CSV (comma-separated values: valeurs séparées par des virgules). La Library Reference est certes très explicative à ce...
Comment lire un fichier ligne par ligne VoirComment lire un fichier ligne par ligne Préambule Boucle while Syntaxe Exemple Astuces Bonus Boucle for Syntaxe Préambule Une des erreurs les plus communes dans l'apprentissage des scripts "bash" sous GNU/LInux pour lire un fichier...
Excel - Convertir fichier(s) CSV / XLS VoirComme dit dans le titre, cette application convertit des fichiers CSV en fichiers XLS N’est pas nécessaire pour Excel 2007, ce dernier faisant la conversion automatiquement La conversion n’ayant pas de mise en forme, en cas de modification...
Fichier CSV VoirFormat CSV Un fichier CSV est un fichier tableur, contenant des données sur chaque ligne séparés par un caractère de séparation (généralement une virgule ou un point-virgule). Comment lire un fichier CSV ? Il peut être lu avec un tableur tel que...
Perl - Les fichiers VoirLa notion de filehandle On appelle filehandle (traduisez descripteur de fichier), dans un programme Perl, le nom permettant de manipuler une connexion d'entrée-sortie (les entrées-sorties standards vues précédemment sont connues par les filehandles...

1

Vince17, le 24 jan 2007 à 18:48:51

C'est bon j'ai trouvé

Répondre à Vince17

2

bob031, le 24 jan 2007 à 19:08:34

Bonjour,

J'ai lu ton poste m'ai j'ai séché !
Si tu as la réponse je suis preneur !

bob

Répondre à bob031

6

Vince17, le 26 jan 2007 à 13:48:31

Donc voici mon script actuel qui marche :d

#!/usr/bin/perl

open DB,  ">/var/named/toto.fr";
open REV, ">/var/named/10.in-addr.arpa.rev";

$j = 0;
$i = 0;
open ADRIP, "tableip.csv";
while($ligne = <ADRIP>)   
 {
   ($nom[$j],$adr[$j]) = split /;/,$ligne;
#print "test  $j $nom[$j] $adr[$j] \n";
   $j++;
#print "fin de la boucle $j \n";
 }
close ADRIP;

print DB 
	"\$\TTL\t86400\
	@\tIN\tSOA\tent.toto.fr. root.toto.fr. (
	1997022700\t; Serial
	28800\t; Refresh
	14400\t; Retry
	3600000\t; Expire
	86400 )\t; Minimum\n
	@\tIN\tNS\tent.toto.fr
	ent\tIN\tA\t10.2.2.145
	test\tIN\tCNAME\tent\n";

print REV
        "\$\TTL\t86400\
        @\tIN\tSOA\tent.totofr. root.toto.fr. (
        1997022700\t; Serial
        28800\t; Refresh
        14400\t; Retry
        3600000\t; Expire
        t86400 )\t; Minimum\n
        @\tIN\tNS\tent.toto.fr.
        1\tIN\tPTR\tent.toto.fr.\n";

while($i<$j) 
   {
  	print DB  "$nom[$i]\tIN\tA\t$adr[$i]\n";
	print REV "$adr[$i]\tIN\tPTR\t$nom[$i]\n";
        $i++;
   } 

close DB; close REV;

Répondre à Vince17

3

lami20j, le 24 jan 2007 à 19:46:55

Salut,

C'est bien que tu as trouvé :-)
Cependant la manière dont tu as écrit ton script n'est pas très propre ni correcte

Par exemple


$nom[$j] = ($hote,$IP);

tu affectes à un scalaire une liste, ce qui veut dire que $nom[$i] va prendre la valeur de $IP

l'opérateur virgule sait s'il est dans un contexte scalaire ou dans un contexte de liste

Autre exemple

($hote,$IP) = split /;/, <ADRIP>;
ici tu dois faire un split pour chaque ligne de fichier dans ton cas $_ et pas <ADRIP>

et d'ailleurs à chaque passage de ligne les variables sont remplacées et à la fin du fichier tu n'auras que la dernière ligne splitée

Pour ne pas parler de l'horreur :-))
print DB
"\$\TTL\t86400\n",
"@\tIN\tSOA\t ent.toto.fr. root.toto.fr. (\n",
"\t\t\t\t1997022700\t; Serial\n",
"\t\t\t\t28800\t; Refresh\n",
"\t\t\t\t14400\t; Retry\n",
"\t\t\t\t3600000\t; Expire\n",
"\t\t\t\t86400 )\t; Minimum\n",
"\n",
"@\tIN\tNS\tent.toto.fr\n",
"ent\tIN\tA\t10.2.2.145\n",
"test\tIN\tCNAME\tent\n";


Moi j'aurais écrit comme ça

$t="\t" x 4; # le nombre de tabulations

print DB "\$\TTL\t86400
@\tIN\tSOA\t ent.toto.fr. root.toto.fr. (
${t}1997022700\t; Serial
${t}28800\t; Refresh
${t}14400\t; Retry
${t}3600000\t; Expire
${t}86400 )\t; Minimum\n
@\tIN\tNS\tent.toto.fr
ent\tIN\tA\t10.2.2.145
test\tIN\tCNAME\tent\n";  
A ne pas oublier non plus d'indenter ton code. lami20j

Répondre à lami20j

4

Vince17, le 25 jan 2007 à 13:58:57

Merci lami20j, je découvre le perl donc je m'aide au mieu sur les doc que je trouve et j'avais trouvé une tel écriture pour le print DB :s
effectivement pour ($hote,$IP) = split /;/, <ADRIP>; ça n'allait pas faut une variable
désolé pour l'indentation sur mon script c'est bien indenté ;)

Répondre à Vince17

5

lami20j, le 25 jan 2007 à 16:40:01

Re,

désolé pour l'indentation sur mon script c'est bien indenté
En ce cas utilise le balises code

Pour utiliser les balises code :
1. tu selectionne le texte à mettre entre les balises
2. tu fait clic sur le bouton Code qui est à côté de

CCM G I S 
lami20j

Répondre à lami20j

7

Vince17, le 26 jan 2007 à 14:41:25

Maintenant j'ai un autre souci
j'ai plusieurs de zone reverse dns dans mon fichier csv les adresses ne sont pas trié donc je cherche comment faire pour qu'il compare l'adresse et rentre bien dans son fichier reverse dans ma config.

j'ai fait

while($i<$j)
{
  if ($adr[$i] eq 128)
    {
     print REV2 "$adr[$i]\tIN\tPTR\t$nom[$i]\n";
    }
    elsif ($adr[$i] eq 194)
    {
     print REV3 "$adr[$i]\tIN\tPTR\t$nom[$i]\n";
    }
    else
    print REV1 "$adr[$i]\tIN\tPTR\t$nom[$i]\n";
  $i++;
}

close REV1; close REV2; close REV3


Bien sur j'intègre ça au script ci-dessus ;) (et j'ai bien ouvert les 3 REV)
Au résultat il me mets toutes les ip dans le REV1

Répondre à Vince17

8

lami20j, le 26 jan 2007 à 20:25:08

Salut,

je vais me pencher demain sur ton problème :-)

cependant j'aurai besoin de ton fichier tableip.csv à moins qu'il est confidentiel.

je vais reécrire ton script (la manière dont tu as écrit le tien je n'aime pas trop, même si en Perl on est libre de faire ce qu'on veux, à savoir que c'est bien d'avoir une certaine discipline) et je vais te donner des explications, biensûr si ça t'interesse ;-)

Par exemple
open DB, ">/var/named/toto.fr";

C'est correct :-)
Toutefois c'est bien d'utiliser un test dans le cas qu'on ne peux pas créer le fichier en mode écriture.

Voilà par exemple plusieurs façon d'ouvrir un fichier en écriture (en gras c'est ceux qu'on préfére en général et en particulier avec la version or die)

unless (open(F_WRITE,">$fichier")) { die "E/S : $!\n" }
if (!open(F_WRITE,">$fichier"))    { die "E/S : $!\n" }

die "E/S : $!\n"   unless open(F_WRITE,">$fichier");
die "E/S : $!\n"   if !open(F_WRITE,">$fichier");

open(F_WRITE,">$fichier") || die "E/S : $!\n";
open F_WRITE,">$fichier"  or die "E/S : $!\n";
Donc tous les 6 lignes de code font exactement la même chose :-)
A choisir celle qui te conviens.

A toi.
lami20j

Répondre à lami20j

9

 Vince17, le 1 fév 2007 à 14:34:11

Désolé du retard mon fichier csv c'est tout simple
c'est du type

toto;10.2.2.124
mimi;10.2.1.152
zozo;194.5.210.51
martin;194.5.210.10
dupon;194.5.210.81
dada;192.1.8.71
lulu;192.1.8.102
.... et ainsi de suite

Répondre à Vince17
Collection CommentÇaMarche.net