Posez votre question Signaler

[Perl] souci lecture fichier csv

Vince17 - Dernière réponse le 1 févr. 2007 à 14:34
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;
Lire la suite 

[Perl] souci lecture fichier csv »

9 réponses
Réponse
+0
moins plus
c'est bon j'ai trouvé
bob031 - 24 janv. 2007 à 19:08
bonjour,

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

bob
Vince17 - 26 janv. 2007 à 13:48
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;
Ajouter un commentaire
Réponse
+0
moins plus
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.
Vince17 - 25 janv. 2007 à 13:58
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é ;)
Ajouter un commentaire
Réponse
+0
moins plus
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 
Ajouter un commentaire
Réponse
+0
moins plus
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
Ajouter un commentaire
Réponse
+0
moins plus
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.
Vince17 - 1 févr. 2007 à 14:34
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
Ajouter un commentaire
Ce document intitulé « [Perl] souci lecture fichier csv » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Dossier à la une
5 extensions si vous voulez revenir à l'ancien Facebook