Joseph Tux
Opérateurs « .. » et « ... »

Traiter des fichiers par blocs de lignes.

mercredi 25 novembre 2009 par webmaster

Ce script ne fait rien d’autre que d’afficher ce qu’il fait, au fur et à mesure qu’il le fait ..

traiter plusieurs fichiers
   fractionnés en blocs ( séparés par une ligne vide )
       chaque ligne du bloc étant examinée à son tour

Il peut servir de base pour traiter les blocs, les lignes des blocs ..

Il illustre essentiellement l’utilisation de l’ opérateur d’intervalle « .. »

Le script

PDF - 5.5 ko
Le script en l’état v 1.03
encore à peine sortie du four.. à compléter, deboguer..
#! /usr/bin/perl
use warnings;
use diagnostics;
use strict;
use Carp;    #pour remplacer "die" par "croak" et "warn" par "carp"
use File::Glob qw(:globally :case);    # jocker du shell ligne de commande ? *

## TRAITER LES FICHIERS PAR BLOCS DE LIGNES
## SÉPARÉS PAR DES LIGNES VIDES ( /^$/ )
## Les versions 1.x prennent une liste de fichiers en ligne de commande
## (avec "File::Glob" : recommandation de Damian Conway )

## Les versions 0.x ne prenaient pas d'argument ( ils étaient imposés dans le programme )
## version 0.02 Afficher aussi le nombre de doublons PAR BLOC
## Modification de l'affichage
## version 0.01 Cannevas à 3 boucles imbriquées: fichiers−>blocs−>lignes
## Ici affichage global du nombre des doublons sélectionnés ( pas par bloc )
## (y a plus qu' à .. )

#### Référence bibliographique:
#−−Perl en action 6.8 pp 209 sqq
#−−
#−−Utiliser les OPERATEURS D'INTERVALLE: .. ou ...
#−−
#−−# Traitement de chaque ligne
#−−while (<>) {
#−− if (/Motif_debut/ .. /Motif_fin/) {
#−− #Chaque ligne entre les lignes comportant ces 2 motifs est traitée
#−− }
#−−} # FIN du traitement
#−−
#−−.. accepte que Motif_debut et Motif_fin soient sur la même ligne => ( reconnaissance: true )
#−−... ne reconnait pas une telle ligne => ( non reconnaissance: false )
#−−
#−−
#−−#"
#−−Discussion
#−−
#−−.. ou ...
#−−renvoient vrai à partir de la reconnaissance du 1er motif,
#−− à chaque ligne suivante, jusqu'à la reconnaissance du 2e motif

#−−−−
#Exemple: fichiers de listes de doublons à traiter ( par exemple, en faire des liens physiques )
# avec "fdupes −r /un/chemin/"
# il y a plusieurs fichiers: un par système de fichier ( pour faire des liens physiques ! )

#traiter une série de fichiers

my @fichiers_de_doublons = <@ARGV>;    # Syntaxe de File::Glob

# TODO IMPLIQUE LE TRAITEMENT D'ERREURS
my $numero_fichier = 0;
my $toutes_lignes;        # compte ( toutes ) les lignes par fichier
my $blocs_retenus;        # compte les lignes (retenues) par fichier
my $num_ligne_retenue;    # compte les lignes par fichier
my $num_ligne_par_bloc;
FICHIER:
foreach my $fichier_de_doublons (@fichiers_de_doublons) {

   $num_ligne_retenue = 0;    #
   $toutes_lignes     = 0;    # compte les lignes par fichier
   $numero_fichier++;
   $blocs_retenus = 0;        # compte les lignes (retenues) par fichier
   print "Fichier N° $numero_fichier \t";    # DEBUG
   print "$fichier_de_doublons\n";            # DEBUG
   open FICHIER_DE_DOUBLONS, "<", $fichier_de_doublons
       or croak("ouverture de $fichier_de_doublons impossible $!");

#extraire les blocs d'un fichier ( blocs séparés par une ligne blanche(=vide ) )

BLOCS:
   while (<FICHIER_DE_DOUBLONS>) {
       chomp;
       $toutes_lignes++;
       print "$toutes_lignes Lignes explorées:\t";    #DEBUG
       print "$_ ";                                    #DEBUG
       if ( /^$/ .. /^$/ ) {                           ## NOUVEAU BLOC

           #Chaque ligne entre les lignes vides est traitée
           #traiter chaque ligne du bloc
           $blocs_retenus++;
           $num_ligne_par_bloc = 0;
           print "Fin du bloc n° $blocs_retenus \n";    #DEBUG

       LIGNE:

           #Doit elle être la référence ?

           #si oui: Faire une copie sans accès écriture
           # attention aux modif. involontaires avec les liens physiques !

           #Transformer les doublons en liens−physiques
       }
       else {

## C'est ici que les lignes du bloc seront traitées !
           #print "$_ \n"; # DEBUG
           $num_ligne_retenue++;
           $num_ligne_par_bloc++;

           # print "Ligne retenue: N° $num_ligne_retenue\n" ; #DE

           print "Ligne retenue: n° $num_ligne_par_bloc\n";    #DEBUG

       }    ## Fin de if
   }    ## Fin de while BLOC
   close FICHIER_DE_DOUBLONS;
   print
       "\n −> $num_ligne_retenue lignes retenues et $blocs_retenus blocs dans


le fichier n° $numero_fichier; \n";    #DEBUG

   #print "Fin du fichier de doublons n° $numero_fichier\n\n"; #DEBUG
}    ## Fin de foreach $fichier_de_doublons

print "FINI\n";    #DEBUG
exit 1;

Opérateurs « bloc »

Si j’ai bien compris  [1] , /debut/ .. /fin/ permet d’isoler tout bloc qui commence par /debut/ et se termine par /fin/ , même si /debut/ = /fin/ , alors que /debut/ ... /fin/ ratera une marche, si la fin d’un bloc est aussi le début du bloc suivant ( cas où /debut/ = /fin/ ), et ne reconnaîtra plus qu’un bloc sur deux dans ce cas !

Mon script envisage des fichiers où chaque bloc est séparé du suivant par une (seule) ligne vide ( /^$/ ) qui est donc à la fois debut et fin.

File ::Glob

Ce script utilise le module standard File ::Glob, avec sa syntaxe < >.

Le script a été testé avec des noms de fichiers invraisemblables, des trous et des caractères de malade, et il est passé apparemment sans dommage ( contrairement à la commande wc qui a pleuré ! ) [2]

Résultat

résultat de la commande suivante :

time ./Extraire_un_bloc_de_lignes.1.03 "/home/tmp/test/fdupes-r*" | egrep "blocs dans le fichier"

-> 47418 lignes retenues et 11487 blocs dans le fichier n° 1;
-> 317182 lignes retenues et 13857 blocs dans le fichier n° 2;
-> 594 lignes retenues et 102 blocs dans le fichier n° 3;

real    0m3.973s
user    0m3.204s
sys     0m0.392s

[1] Travaux pratiques autodidactiques, sans aucune garantie, qu’on se le dise !

[2] avec 3 fichiers de doublons de : 27k, 5m, 38m


Accueil du site | Contact | Plan du site | | Statistiques du site | Visiteurs : 59 / 11552

Suivre la vie du site fr  Suivre la vie du site GNU, LINUX, BSD, LL  Suivre la vie du site AIDES GNU/LINUX  Suivre la vie du site PERL   ?

Site réalisé avec SPIP 2.1.12 + AHUNTSIC

Creative Commons License