Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. ###raw>post.musername###
    Futur Membre du Club
    [Archive::zip] Effectuer un traitement récursif des fichiers
    Bonjour,

    J'ai un problème avec le script que je suis entrain d'écrire.

    Je dois dézipper une série de fichier "daily_econtrat1.zip, daily_econtrat2.zip etc etc"

    Dans la plupart de ces archives, il y a un fichier log, mais dans certaines il y a plusieurs autres archives qui contiennent un fichier log chacun.

    Je vous mets déjà ce que j'ai effectué :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    use strict;use warnings;
    use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
    use File::Find;
    use Archive::Zip qw/ :ERROR_CODES :CONSTANTS /;
     
    my $n = 0;
     
    sub recherche {
     if (-f){++$n if $File::Find::name =~ /\.zip/;}
    }
     
    find(\&recherche,"C:\\tests\\logs\\Securitas\\");
    $n += 10;
     
    my $econtrat_zip = '';
    my $econtrat_log = '';
    my $i = 0;
    my $zip = Archive::Zip->new();
    for ($i; $i < $n; $i++){
     
            $econtrat_zip = 'C:\\tests\\logs\\Securitas\\daily_econtrat_log' . $i . '.zip';
            $econtrat_log = 'C:\\tests\\logs\\Securitas\\daily_econtrat_log' . $i . '.log'; 
     
            unless ( $zip->read( $econtrat_zip ) == AZ_OK ) {  
     
        die 'read error';
    }
     
    my @files = $zip->memberNames();  
     
          unzip $econtrat_zip => $econtrat_log || die "Decompression impossible";                   #Décompression
          #unlink $econtrat_zip;
     
    }


    j'ai réussi à voir dans @files la liste des fichiers à l’intérieur des archives (il me ressort donc des .log et des .zip) Mais comme vous le voyez la méthode "unzip" s'applique uniquement au zip ciblé. Je ne sais pas comment utiliser unzip sur les membres si il y a des archives à l’intérieur. Quelqu'un aurait une idée ?
      0  0

  2. #2
    Membre éprouvé
    memberNames liste les noms de fichiers contenus dans ton archive. Tu peux parcourir chacun et suivant son extension tu appliques le bon traitement.

    Sinon, en utilisant membersMatching (link), tu peux récupérer les fichiers se finissant en .zip ou en .log, puis appliquer l'opération voulue.

    À toi de voir quelle solution tu préfères.
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

  3. ###raw>post.musername###
    Futur Membre du Club
    Bonjour, merci pour votre réponse.

    J'essaye d'utiliser la méthode membersMatching('.*\.zip'), j'arrive a dézziper récursivement mais pas à assigner un nouveau nom aux archives (ce qui en résulte une réecriture des archives au fur et à mesure du traitement. J'ai du louper quelque chose. Je vous poste ce que j'ai déjà fait :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
     
    use strict;use warnings;
    use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
    use File::Find;
    use Archive::Zip qw/ :ERROR_CODES :CONSTANTS /;
     
    my $n = 0;
     
    sub recherche {
     if (-f){
     	++$n 
     	if $File::Find::name =~ /\.zip/;
     }
    }
     
    find(\&recherche,"C:\\tests\\logs\\Securitas\\");
    $n--;
     
    my $econtrat_zip = '';
    my $econtrat_log = '';
    my $econtrat_membre_zip = '';
    my $zip = Archive::Zip->new();
    my $pathmembre = "C:\\tests\\logs\\Securitas\\membres\\";
     
    for (my $i = 0; $i < $n; $i++){
     
            $econtrat_zip = 'C:\\tests\\logs\\Securitas\\daily_econtrat_log' . $i . '.zip';
     
     
            unless ( $zip->read( $econtrat_zip ) == AZ_OK ) {  
        	die 'erreur de lecture';
    }
     
    	my @memberZip = $zip->membersMatching( '.*\.zip' );
     
        my $nb = @memberZip;
     
        foreach my $membre(@memberZip){
     
        		for (my $j = 0; $j < $nb; $j++){
     
        		$econtrat_mzip = 'daily_econtrat_log_membre' . $j . '.zip';
        	    $zip->extractMember($membre, "$pathmembre\\$econtrat_mzip");
        	}
     
     
        }
     
    }


    Le problème vient peut être du fait qu'il y a un répertoire avant les archives filles. arborescence des différents types de logs :

    - daily_econtrat_log0.zip
    -> répertoire /tmp
    -> /econtrat.log

    - daily_econtrat_log14.zip
    -> répertoire /tmp
    -> /econtrat.log
    -> /econtrat.1.zip
    -> econtrat.2017-30_06.log


    Le résultat de mon script dezippe tous les zips "mère" en .log (cela fonctionne très bien pour les archives ne comprenant qu'un dossier puis le log) cela dezippe également les archives filles (dans un dossier /tmp, meme pas dans le chemin que je lui ai donné...) mais les archives à l’intérieur de ce dossier sont réécrite par le traitement des autres archives filles. Impossible de leur assigner un nom unique.

    Merci pour votre aide, j'ai parfois l'impression d'être idiot devant un code de 20 lignes ...
      0  0

  4. #4
    Membre éprouvé
    ta dernière boucle for est la source de ton problème, pour chaque zip dans ton archive, elle va reprendre à 0 et donc écraser ce que tu as déjà extrait
    de plus vu que tu parcours déjà ta liste avec le foreach, tu vas réécrire tous tes fichiers.

    donc supprime ta boucle foreach, ou utilise une autre façon de nommer
    exemple en supprimant et renommant avec le fichier log originel
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    my @memberZip = $zip->membersMatching( '.*\.zip' );
    for (my $j = 0; $j < $nb; $j++){
    	my $econtrat_mzip = 'daily_econtrat_log' . $i .'_membre' . $j . '.zip';
    	$zip->extractMember($memberZip[$j], "$pathmembre/$econtrat_mzip");
    }

    De plus, là tu ne fais qu'extraire la 2è archive de la première, il faut encore extraire le fichier log à l'intérieur de la 2è archive
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes