[Perl] souci lecture fichier csv

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

5 réponses

  1. c'est bon j'ai trouvé
    0
    1. bonjour,

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

      bob
      0
    2. @bob031donc 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;
      0
  2. Modérateur
    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.
    0
    1. 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é ;)
      0
  3. Modérateur
    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 
    0
    1. 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
      0
      1. Modérateur
        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.
        0
        1. 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
          0