IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Langage Perl Discussion :

conseil pour un script perl


Sujet :

Langage Perl

  1. #21
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par Lolo78 Voir le message
    OK, commençons par la ligne sans doute la plus difficile:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my %needed = map { $_ => 1 } @wanted, @needed;
    Cette ligne prend tous les éléments des deux tableaux @wanted et @needed alimentés aux lignes précédentes et construit un hachage dont les clefs sont les éléments de ces deux tableaux et les valeurs le chiffre 1 (une valeur arbitraire qui a l'avantage d'être vraie si on la teste dans un contexte booléen).
    C'est exact mais peut-être un peu rapide... Je vais essayer de détailler un peu plus. L'objectif ici est de définir une table de hachage, %wanted, permettant d'optimiser (on verra plus tard comment) la lecture des lignes en se limitant à celles effectivement utiles dans notre cas. Ces dernières sont celles commençant par CLASS, SCHED, SCHEDPOOL et INCLUDE, plus POOL qu'on utilisera comme valeur de substitution pour SCHEDPOOL lorsque ce dernier vaut *NULL*.

    Allons-y petit à petit, en réétablissant le contexte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my @wanted = qw(CLASS SCHED SCHEDPOOL INCLUDE);
    my @needed = qw(POOL);
    my %needed = map { $_ => 1 } @wanted, @needed;
    En ligne 1 ci-dessus, on déclare la liste @wanted, et on l'initialise avec les valeurs 'CLASS', 'SCHED', 'SCHEDPOOL', et 'INCLUDE'. On aurait pu écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @wanted = ('CLASS', 'SCHED', 'SCHEDPOOL', 'INCLUDE');
    mais l'utilisation de l'opérateur qw évite de s'encombrer des apostrophes et des virgules, et on gagne en lisibilité.

    Que représente cette variable @wanted ? C'est la liste des clés que l'on veut faire apparaître dans les lignes générées. On s'en sert ligne 3 et plus tard dans le programme, donc selon le principe 'DRY' (Don't Repeat Yourself -- ne vous répétez pas), on la définit une fois pour toutes, et surtout une seule fois.

    La variable @needed représente la liste des clés dont on a besoin en plus de celles que l'on va afficher. A ce stade elle ne contient qu'une seule valeur, mais peut-être y en aura-t-il d'autres dans le futur si on est amené à faire évoluer le programme... Ça ne coûte pas grand chose d'en faire une liste. Je reconnais par contre qu'elle est peut-être mal nommée, en relation avec la table de hachage %needed. Je l'avais introduite surtout pour faire réaliser aux lecteurs qui n'en seraient pas forcément conscients qu'en Perl on peut définir et faire coexister des entités de type différent portant le même nom : la liste @foobar, la table de hachage %foobar, le scalaire $foobar, la fonction &foobar, le glob *foobar. Quoi qu'il en soit, la table de hachage %needed vise à représenter les clés qu'on doit lire, alors que @needed liste les clés qu'on doit lire en plus de celles figurant dans @wanted... Petite maladresse donc, potentiellement source de confusion, que l'on peut corriger en rebaptisant @needed en @extra :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my @wanted = qw(CLASS SCHED SCHEDPOOL INCLUDE);
    my @extra  = qw(POOL);
    my %needed = map { $_ => 1 } @wanted, @extra;
    Intéressons nous maintenant à cette fameuse ligne 3. Clairement, on déclare la table de hachage %needed, et on va l'initialiser en invoquant l'opérateur map. Cet opérateur peut être invoqué de deux manières : map EXPR, LIST ou map BLOCK LIST. J'ai tendance à utiliser systématiquement la seconde forme, que je trouve plus claire, mais c'est affaire de goût. Ici BLOCK est { $_ => 1 }, et LIST est @wanted, @extra. Il est important de comprendre que lorsque des listes figurent dans une liste, elles sont aplaties pour produire la liste finale. Autrement dit, les expressions suivantes sont équivalentes :
    @wanted, @extra
    (@wanted, @extra)
    @wanted, ('POOL')
    @wanted, 'POOL'
    'CLASS', ('SCHED', ('SCHEDPOOL', ('INCLUDE', ('POOL'))))
    ((((('CLASS'), 'SCHED'), 'SCHEDPOOL'), 'INCLUDE'), 'POOL')
    au final elles se résolvent toutes identiquement après aplatissement à la liste
    'CLASS', 'SCHED', 'SCHEDPOOL', 'INCLUDE', 'POOL'
    et c'est sur cette liste que map va opérer.

    Que fait map en l'occurrence ? Pour chaque élément de la liste il va évaluer le BLOCK { $_ => 1 } et construire la liste des résultats obtenus. A l'intérieur du BLOCK, $_ est un alias sur l'élément courant de la liste, celui sur lequel on travaille. L'expression $_ => 1 construit la liste ($_, 1), et c'est la valeur de retour du BLOCK. Map va donc construire la liste de listes suivante :
    ('CLASS', 1), ('SCHED', 1), ('SCHEDPOOL', 1), ('INCLUDE', 1), ('POOL', 1)
    qui du fait de l'aplatissement évoqué ci-dessus est en fait
    'CLASS', 1, 'SCHED', 1, 'SCHEDPOOL', 1, 'INCLUDE', 1, 'POOL', 1
    Que se passe-t-il lorsqu'on affecte cette liste à la table de hachage %needed ? La liste est décomposée en couples consécutifs (clé, valeur) et pour chaque couple on affecte valeur à la position clé dans la table, c'est à dire qu'on exécute $h{clé} = valeur. Autrement dit, tout se passe comme si on avait effectué la séquence d'opérations suivantes :
    $h{'CLASS'} = 1;
    $h{'SCHED'} = 1;
    $h{'SCHEDPOOL'} = 1;
    $h{'INCLUDE'} = 1;
    $h{'POOL'} = 1;
    (Noter que si une clé figure plusieurs fois dans la liste, c'est la dernière valeur associée qui l'emporte...)

    En fait cette fameuse ligne 3 est équivalente à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    my %needed;
    foreach my $cle (@wanted, @extra) {
        $needed{$cle} = 1;
    }
    ou à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    my %needed;
    foreach (@wanted, @extra) {
        $needed{$_} = 1;
    }
    ou encore à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my %needed;
    $needed{$_} = 1 foreach @wanted, @extra;
    (on aurait pu utiliser for en lieu et place de foreach ci-dessus). Peut-être ces formes sont-elles plus claires pour certains. La dernière en particulier paraît plus compacte que notre ligne 3 avec son map. Est-elle pour autant préférable ?

    A mon avis non, et la raison tient au fait que ces formes séparent la déclaration de la variable %needed de son initialisation. Pour un programmeur expérimenté, il y a quelque chose de troublant, de vaguement malsain et inquiétant, à déclarer une variable qui reste -- aussi brièvement que cela soit -- non initialisée. L'initialisation immédiate par map évite ce malaise. Ça paraît peut être un détail comme ça, mais ces détails finissent par faire une grosse différence sur le long terme. Par ailleurs, c'est un idiome (ou si vous préférez, une manière de coder) parfaitement reconnaissable pour un programmeur Perl ayant un peu de bouteille. De plus cet idiome est bien connu du compilateur perl lui même, qui est susceptible de l'optimiser.

    Notons cependant que les boucles ci-dessus sont parfaitement légitimes lorsque la table %needed existe déjà, par exemple dans la situation suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    my @wanted = qw(CLASS SCHED SCHEDPOOL INCLUDE);
    my @extra  = qw(POOL);
    my %needed = map { $_ => 1 } @wanted, @extra;
    ...
    my @more = ...;
    $needed{$_} = 1 foreach @more;
    Ici en ligne 3 on initialise la table de hachage %needed comme précedemment, tandis qu'en ligne 5, on vient compléter (ou mettre à jour) cette table : les seules entrées affectées sont celles dont les clés figurent dans @more, et l'utilisation d'une boucle est alors tout à fait adaptée.

    Bon, ça suffit peut être pour aujourd'hui ... Je reviendrai plus tard sur les autres points.

    Au fait, n'hésitez pas à marquer votre appréciation (ou votre dégoût ) pour ce message en utilisant les boutons (ou ) ci dessous à droite... Ce genre de rédaction prend pas mal de temps, et un peu de feedback des lecteurs est toujours bienvenu !
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  2. #22
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par cmcmc Voir le message

    Au fait, n'hésitez pas à marquer votre appréciation (ou votre dégoût ) pour ce message en utilisant les boutons (ou ) ci dessous à droite... Ce genre de rédaction prend pas mal de temps, et un peu de feedback des lecteurs est toujours bienvenu !
    C'est fait.

    Et n'hésite pas à "moinssoyer" mon message si tu trouvais mon explication inadéquate.

  3. #23
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Bonjour

    @lolo78 et@cmcmc
    Tout d'abord je tenais à vous remercier pour votre aide.
    Vos explications sont vraiment très claires.
    J'ai d'ailleurs voté pour mon "dégout" largement positif pour vos messages respectifs. Je m'attendais vraiment pas à cela
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  4. #24
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Bonjour,

    Je commence à comprendre le script.
    Par contre, je viens de me rendre compte d'une complication.
    En effet,lorsque l'on a le mot INCLUDE et qu'il est suivi du mot SET.
    Il faut prendre tout ce qu'il y a après
    INCLUDE SET EXCLUDE = *snapshot
    INCLUDE SET HIST=Y
    INCLUDE SET HIST=N
    INCLUDE SET EXCLUDE=*snapshot
    Pas simple sachant que tout le script est bâti sur seulement les deux premiers champs
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  5. #25
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par JUSTIN Loïc Voir le message
    Bonjour,

    Je commence à comprendre le script.
    Par contre, je viens de me rendre compte d'une complication.
    En effet,lorsque l'on a le mot INCLUDE et qu'il est suivi du mot SET.
    Il faut prendre tout ce qu'il y a après

    Pas simple sachant que tout le script est bâti sur seulement les deux premiers champs
    Bonjour,

    Ta question initiale avait une très bonne propriété : tu donnais précisément les données de départ, et ce que tu voulais obtenir. Fais pareil ici : donne un ou plusieurs exemple(s) complet(s) de fichier(s) d'entrée, et le ou les fichier(s) de sortie correspondant(s). A partie de ça on pourra discuter
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  6. #26
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Bonjour @cmcmc

    Mes données n'ont pas changé.
    Mais je me suis rendu compte que j'avais parfois ce type d'enregistrement
    CLASS CL-13D-DATA1NDMP *NULL* 0 701000 0 *NULL*
    NAMES
    INFO 19 0 0 0 *NULL* 0 0 2147483647 0 0 0 0 0 0 0 0 0 0 1347525797 105EA904F3E511E0990E0021284F59EA 1 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 3 14
    KEY *NULL*
    BCMD *NULL*
    RCMD *NULL*
    RES VSU-fifila02-P1A *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL*
    POOL DDR-A-P1A-R3 NetBackup NetBackup NetBackup NetBackup NetBackup NetBackup NetBackup NetBackup NetBackup
    FOE 0 0 0 0 0 0 0 0 0 0
    SHAREGROUP *ANY*
    DATACLASSIFICATION Silver
    CLIENT fifila02 NDMP NDMP 0 0 0 0 *NULL*
    INCLUDE SET EXCLUDE = *snapshot
    INCLUDE SET HIST=Y
    INCLUDE /vol/vol_13D_SMIS_Prod/applis_13dexp
    INCLUDE /vol/vol_13D_SMIS_Prod/applis_13dord
    INCLUDE /vol/vol_13D_SMIS_Prod/applis_13dsms
    INCLUDE SET HIST=N
    INCLUDE /vol/vol_13D_SMIS_Prod/OA_v11.5.10.2_13dsms
    SCHED SCH-13D-DATA1NDMP-FR3 0 1 604800 3 0 0 0 *NULL* 0 0 0 0 0 0 -1 0
    SCHEDWIN 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    SCHEDRES *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL*
    SCHEDPOOL *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL*
    SCHEDRL 3 1 1 1 1 1 1 1 1 1
    SCHEDFOE 0 0 0 0 0 0 0 0 0 0
    SCHEDSG *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL* *NULL*
    Et que dans ce cas j'ai besoin des informations qui se trouvent aprés le mot SET
    Donc actuellement, j'ai ce resultat
    CL-13D-DATA1NDMP;SCH-13D-DATA1NDMP-FR3;DDR-A-P1A-R3;SET;SET;/vol/vol_13D_SMIS_Prod/applis_13dexp;/vol/vol_13D_SMIS_Prod/applis_13dord;/vol/vol_13D_SMIS_Prod/applis_13dsms;SET;/vol/vol_13D_SMIS_Prod/OA_v11.5.10.2_13dsms
    Alors que je devrais avoir
    CL-13D-DATA1NDMP;SCH-13D-DATA1NDMP-FR3;DDR-A-P1A-R3;SET_EXCLUDE_=_*snapshot;SET_HIST=Y;/vol/vol_13D_SMIS_Prod/applis_13dexp;/vol/vol_13D_SMIS_Prod/applis_13dord;/vol/vol_13D_SMIS_Prod/applis_13dsms;SET_HIST=N;/vol/vol_13D_SMIS_Prod/OA_v11.5.10.2_13dsms
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  7. #27
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    J'ai rajouté un peu de couleur dans ton message :

    Citation Envoyé par JUSTIN Loïc Voir le message
    Bonjour @cmcmc

    Mes données n'ont pas changé.
    Mais je me suis rendu compte que j'avais parfois ce type d'enregistrement
    ...
    INCLUDE SET EXCLUDE = *snapshot
    INCLUDE SET HIST=Y
    INCLUDE /vol/vol_13D_SMIS_Prod/applis_13dexp
    INCLUDE /vol/vol_13D_SMIS_Prod/applis_13dord
    INCLUDE /vol/vol_13D_SMIS_Prod/applis_13dsms
    INCLUDE SET HIST=N
    INCLUDE /vol/vol_13D_SMIS_Prod/OA_v11.5.10.2_13dsms
    ...
    Et que dans ce cas j'ai besoin des informations qui se trouvent aprés le mot SET
    Donc actuellement, j'ai ce resultat
    ...
    Alors que je devrais avoir
    CL-13D-DATA1NDMP;SCH-13D-DATA1NDMP-FR3;DDR-A-P1A-R3;SET_EXCLUDE_=_*snapshot;SET_HIST=Y;/vol/vol_13D_SMIS_Prod/applis_13dexp;/vol/vol_13D_SMIS_Prod/applis_13dord;/vol/vol_13D_SMIS_Prod/applis_13dsms;SET_HIST=N;/vol/vol_13D_SMIS_Prod/OA_v11.5.10.2_13dsms
    En fait apparemment ce qu'il faut, c'est récupérer toutes les valeurs pour INCLUDE, en les joignant par des underscores. Ce n'est pas très dur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        ...
        my ($key, $first, @rest) = split;
        next unless $needed{$key};
        $first = join('_', $first, @rest) if $key eq 'INCLUDE';
        %h = () if $key eq 'CLASS';
        ...
    et il me semble bien que le tour est joué...
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  8. #28
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Merci @cmcmc

    Décomposé de cette façon, cela parait si simple, mais malheureusement, je n'ai pas encore ce réflexe .
    Et en plus cela fonctionne superbement bien.
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  9. #29
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Pour etre entierement complet, il faut que je rajoute une information importante.
    Au lieu de (none), je dois dire
    Sauvegarde gérée par Rman
    Pour cela j'ai besoin de la ligne INFO
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @extra  = qw(POOL INFO);
    et je dis si INFO est different de 4 j'affiche (none) sinon j'indique sauvegarde RMAN
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            if ( $h{INFO}[1] != '4' ) {
            $h{INCLUDE} = ['(none)'] unless exists $h{INCLUDE};
            }
             else {
            $h{INCLUDE} = ['Sauvegarde Rman'] unless exists $h{INCLUDE};
            }
    Mais cela ne fonctionne pas.
    J'ai l'erreur suivante
    Use of uninitialized value in numeric ne (!=) at ./test2.pl line 22, <> line
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  10. #30
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par JUSTIN Loïc Voir le message
    ...
    Pour cela j'ai besoin de la ligne INFO
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @extra  = qw(POOL INFO);
    Extra Je savais bien qu'elle servirait un jour, cette variable
    et je dis si INFO est different de 4 j'affiche (none) sinon j'indique sauvegarde RMAN
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            if ( $h{INFO}[1] != '4' ) {
            $h{INCLUDE} = ['(none)'] unless exists $h{INCLUDE};
            }
             else {
            $h{INCLUDE} = ['Sauvegarde Rman'] unless exists $h{INCLUDE};
            }
    Mais cela ne fonctionne pas.
    ...
    Use of uninitialized value in numeric ne (!=) at ./test2.pl line 22, <> line
    Piège classique... C'est quoi l'index du premier élément d'un tableau ?
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  11. #31
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Effectivement bien vu pour la valeur "extra"
    Sinon, concernant la 1ere valeur d'un tableau c'est 0 et non 1
    Un vrai bleu ...suis-je?
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  12. #32
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Bonjour @cmcmc
    Aprés modification le script fonctionne vraiment correctement.
    Le voici en version presque définitif, en mode débug.
    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
    #!/usr/bin/perl
    use strict;
    use warnings;
    use Data::Dumper;
     
    my $fic1_out="fichier de sortie";
    my @wanted = qw(CLASS SCHED SCHEDPOOL INCLUDE);
    my @extra  = qw(POOL INFO);
    my %needed = map { $_ => 1 } @wanted, @extra;
     
    open (fic1_out,'>',$fic1_out) or die "impossible d'ecrire $fic1_out\n";
    my %h;
    while (<>) {
        chomp;
        my ($key, $first, @rest) = split;
        next unless $needed{$key};
        $first = join('_', $first, @rest) if $key eq 'INCLUDE';
        %h = () if $key eq 'CLASS';
        push @{$h{$key}}, $first;
        if ($key eq 'SCHEDPOOL') {
            print Dumper(\%h);
            if ( $h{INFO}[0] != '4' ) {
            $h{INCLUDE} = ['(none)'] unless exists $h{INCLUDE};
            }
             else {
            $h{INCLUDE} = ['Sauvegarde geree par Rman'] unless exists $h{INCLUDE};
            }
            $_ eq '*NULL*' and $_ = $h{POOL}[0] for $h{SCHEDPOOL}[0];
            print fic1_out +(join ';', map { @$_ } @h{@wanted}), "\n";
            pop @{$h{$_}} for qw(SCHED SCHEDPOOL);
        }
    }
    Petite question.
    Actuellement les informations données en parametre pour le script sont considérées comme des fichiers à traiter.
    J'aimerais pouvoir transmettre le fichier à traiter en 1er argument et en second argument le nom du fichier de sortie.
    Je sais que la récupération de variable se fait avec la variable ARGV
    Mais si j'ajoute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (@ARGV==2) {
    $variable=$ARGV[1];
    }
    Je recupere bien ma variable par contre il considere cette variable comme nom de fichier
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  13. #33
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par JUSTIN Loïc Voir le message
    Bonjour @cmcmc
    Aprés modification le script fonctionne vraiment correctement.
    Le voici en version presque définitif, en mode débug.
    une petite suggestion, au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            if ( $h{INFO}[0] != '4' ) {
            $h{INCLUDE} = ['(none)'] unless exists $h{INCLUDE};
            }
             else {
            $h{INCLUDE} = ['Sauvegarde geree par Rman'] unless exists $h{INCLUDE};
            }
    tu pourrais écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	$h{INCLUDE} = [
    	    ($h{INFO}[0] != '4' )
    	    ? '(none)'
    	    : 'Sauvegarde geree par Rman']
    	  unless exists $h{INCLUDE};
    c'est meilleur car il n'y a pas de duplication de code.

    Citation Envoyé par JUSTIN Loïc Voir le message
    Petite question.
    Actuellement les informations données en parametre pour le script sont considérées comme des fichiers à traiter.
    J'aimerais pouvoir transmettre le fichier à traiter en 1er argument et en second argument le nom du fichier de sortie.
    Je sais que la récupération de variable se fait avec la variable ARGV
    Mais si j'ajoute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (@ARGV==2) {
    $variable=$ARGV[1];
    }
    Je recupere bien ma variable par contre il considere cette variable comme nom de fichier
    L'avantage d'utiliser <> et ARGV plutôt que d'ouvrir un fichier d'entrée dont le nom est passé en paramètre est qu'on peut passer plusieurs fichiers au programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    perl monscript.pl fichier1 fichier2 ...
    (si on n'en passe aucun, le programme lit l'entrée standard STDIN). C'est donc très souple, et à mon avis préférable à l'ouverture explicite de fichiers...

    Pour récupérer la sortie, la manière usuelle est de la rediriger dans un fichier au niveau du shell :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    perl monscript.pl fichier1 fichier2 ... > sortie
    si tu tiens absolument à passer le nom du fichier de sortie en paramètre, alors mets le en premier, comme ça tu pourras quand même passer plusieurs fichiers d'entrée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    perl monscript.pl sortie fichier1 fichier2 ...
    et ajoute les lignes suivantes au début de ton script :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my $outfilename = shift @ARGV;
    open my $of, ">", $outfilename or die "impossible d'ouvrir $outfilename: $! ($^E)";
    et remplace tes print/say par
    Moi j'utiliserai la redirection shell mais tu fais comme tu veux
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  14. #34
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par cmcmc Voir le message
    Moi j'utiliserai la redirection shell mais tu fais comme tu veux
    Oui, c'est pratique, mais moins portable...

  15. #35
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Bonjour
    Merci @cmcmc et @lolo78
    Pour @cmcmc
    si j'ai bien compris ton script. (J'aime bien quand on peut réduire un script de cette façon et qu'il reste compréhensible)
    correspond à => la condition est vraie
    correspond à => sinon ...
    Sinon, pour le fichier de sortie, je vais tester les deux possibilités pour voir ce qui est le plus pratique pour moi.
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  16. #36
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Voici mon script.
    Il est utilisé en lancant la commande suivante :
    fichier.pl ${catalog} nom_du_fichier_en_entre
    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
    #!/usr/bin/perl
    use strict;
    use warnings;
    use Data::Dumper;
     
    my $catalogue;
    if (@ARGV==2) {
    $catalogue=$ARGV[0];
    print "nom du catalogue $catalogue \n";
    shift @ARGV;
    }
    my $fic1_out="fichier_de_sortie_$catalogue";
    my @wanted = qw(CLASS SCHED SCHEDPOOL INCLUDE);
    my @extra  = qw(POOL INFO);
    my %needed = map { $_ => 1 } @wanted, @extra;
     
    open (fic1_out,'>',$fic1_out) or die "impossible d'ecrire $fic1_out\n";
    my %h;
    while (<>) {
        chomp;
        my ($key, $first, @rest) = split;
        next unless $needed{$key};
        $first = join('_', $first, @rest) if $key eq 'INCLUDE';
        %h = () if $key eq 'CLASS';
        push @{$h{$key}}, $first;
        if ($key eq 'SCHEDPOOL') {
            print Dumper(\%h);
            $h{INCLUDE} = [
                ($h{INFO}[0] != '4' )
                ? '(none)'
                : 'Sauvegarde geree par RMAN']
              unless exists $h{INCLUDE};
            $_ eq '*NULL*' and $_ = $h{POOL}[0] for $h{SCHEDPOOL}[0];
            print fic1_out +(join ';', map { @$_ } @h{@wanted}), "\n";
            pop @{$h{$_}} for qw(SCHED SCHEDPOOL);
        }
    }
    Sinon, j'ai encore besoin de faire une modification
    En effet, quand le nombre de ligne INCLUDE dépasse les cinquante, je ne dois rien mettre comme information.
    Comment faire ?
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  17. #37
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Apparemment, j'ai trouvé la solution
    Est-ce la plus judicieuse ???
    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
    #!/usr/bin/perl
    use strict;
    use warnings;
    use Data::Dumper;
    
    my $catalogue;
    if (@ARGV==2) {
    $catalogue=$ARGV[0];
    print "nom du catalogue $catalogue \n";
    shift @ARGV;
    }
    my $fic1_out="fichier_de_sortie_$catalogue";
    my @wanted = qw(CLASS SCHED SCHEDPOOL INCLUDE);
    my @extra  = qw(POOL INFO);
    my %needed = map { $_ => 1 } @wanted, @extra;
    
    open (fic1_out,'>',$fic1_out) or die "impossible d'ecrire $fic1_out\n";
    my %h;
    while (<>) {
        chomp;
        my ($key, $first, @rest) = split;
        next unless $needed{$key};
        $first = join('_', $first, @rest) if $key eq 'INCLUDE';
        %h = () if $key eq 'CLASS';
        push @{$h{$key}}, $first;
        if ($key eq 'SCHEDPOOL') {
            print Dumper(\%h);
            $h{INCLUDE} = [
                ($h{INFO}[0] != '4' )
                ? '(none)'
                : 'Sauvegarde geree par RMAN']
              unless exists $h{INCLUDE};
            if ( @{$h{INCLUDE}} > 50 ) {
            $h{INCLUDE}= [];
            }
            $_ eq '*NULL*' and $_ = $h{POOL}[0] for $h{SCHEDPOOL}[0];
            print fic1_out +(join ';', map { @$_ } @h{@wanted}), "\n";
            pop @{$h{$_}} for qw(SCHED SCHEDPOOL);
        }
    }
    Voir en rouge dans le script.
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  18. #38
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Ca paraît très bien.

    Une remarque,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    open (fic1_out,'>',$fic1_out) or die "impossible d'ecrire $fic1_out\n";
    serait mieux ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    open (fic1_out,'>',$fic1_out) or die "impossible d'écrire $fic1_out:$! ($^E)\n";
    $! et $^E contiennent une explication de l'erreur rencontrée. Ca peut être utile de savoir qu'on n'a pas pu ouvrir (et non écrire à ce stade) le fichier de sortie, par exemple pour des raisons de permissions ou bien parce qu'on a spécifié un fichier dans un répertoire inexistant...

    Et du coup il est bon également de fermer explicitement le fichier en fin de programme, avec une ligne de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    close(fic1_out) or die "erreur d'écriture sur $fic1_out:$! ($^E)\n";
    qui t'indiquera par exemple que le système n'est pas parvenu a écrire complètement le fichier car il n'y a plus de place sur le disque.

    Ceci est utile surtout si tu es sous Windows, car le contenu de $^E peut parfois être plus explicite que celui de $! (sous unix, les deux ont la même valeur).
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  19. #39
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    à @JUSTIN Loïc

    au fait, est ce que tu peux expliquer à ta manière ce que font ces trois lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            $_ eq '*NULL*' and $_ = $h{POOL}[0] for $h{SCHEDPOOL}[0];
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            print fic1_out +(join ';', map { @$_ } @h{@wanted}), "\n";
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            pop @{$h{$_}} for qw(SCHED SCHEDPOOL);
    si tu n'es pas sûr n'hésite pas à demander mais prends ton temps et cherche un peu
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  20. #40
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Citation Envoyé par cmcmc Voir le message
    Ca paraît très bien.

    Une remarque,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    open (fic1_out,'>',$fic1_out) or die "impossible d'ecrire $fic1_out\n";
    serait mieux ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    open (fic1_out,'>',$fic1_out) or die "impossible d'écrire $fic1_out:$! ($^E)\n";
    $! et $^E contiennent une explication de l'erreur rencontrée. Ca peut être utile de savoir qu'on n'a pas pu ouvrir (et non écrire à ce stade) le fichier de sortie, par exemple pour des raisons de permissions ou bien parce qu'on a spécifié un fichier dans un répertoire inexistant...

    Et du coup il est bon également de fermer explicitement le fichier en fin de programme, avec une ligne de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    close(fic1_out) or die "erreur d'écriture sur $fic1_out:$! ($^E)\n";
    qui t'indiquera par exemple que le système n'est pas parvenu a écrire complètement le fichier car il n'y a plus de place sur le disque.

    Ceci est utile surtout si tu es sous Windows, car le contenu de $^E peut parfois être plus explicite que celui de $! (sous unix, les deux ont la même valeur).
    Merci @cmcmc pour cette information, car je ne connaissais pas
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 4 PremièrePremière 1234 DernièreDernière

Discussions similaires

  1. Conseil pour un script de suppression de fichiers en double
    Par doc malkovich dans le forum Langage
    Réponses: 10
    Dernier message: 11/09/2013, 11h17
  2. Réponses: 1
    Dernier message: 29/05/2008, 14h16
  3. Besoin de quelques conseils pour un script java
    Par poussin544 dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 02/03/2006, 10h41
  4. Réponses: 2
    Dernier message: 11/07/2002, 08h31
  5. [web] Cherche un conseil pour un livre perl-tk
    Par Anonymous dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 29/04/2002, 15h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo