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 :

anomyser dates d'un fichier texte txt en sortie un autre fichier texte txt


Sujet :

Langage Perl

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 2
    Points : 2
    Points
    2
    Par défaut anomyser dates d'un fichier texte txt en sortie un autre fichier texte txt
    Bonjour je viens de debuter en perl il ya 1 heure .Mon pb le voici
    la j'ai un bout fichier texte:
    DATE_MIGRATION Date(8) 20100618
    DATE_MIGRATION Date(8) 20100618

    DATE_MIGRATION2 Date(8) 20100619

    DATE_MIGRATION3 Date(8) 20100617

    ...........

    je voudrais rendre anonyme la valeur des dates en générant dautres dates fausses mais qui soient espacee de +-5 ans par exemple cad par ex 20100618 qui en fait 18/06/2010 soit par exemple 20050618 soit 18/06/2005.

    L'idee est donc de creer un deuxieme fichier texte txt contenant des fausses donnee

    Quelqu'un a une idee d'analysr et de code
    SVp

  2. #2
    Inactif  
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 123
    Points : 130
    Points
    130
    Par défaut Petit script
    Bonjour,
    alors après avoir cherché une façon de faire trop compliquée, avec des expressions régulières, etc, j'ai vu comment faire simple et fonctionnel.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    while(<STDIN>) {
      my @arr = split(/ /);
      print $arr[0] . " ";
      print ($arr[1] - 00050000);
      print "\n";
    }
    under construction...

  3. #3
    Membre confirmé
    Avatar de Schmorgluck
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    371
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2006
    Messages : 371
    Points : 558
    Points
    558
    Par défaut
    Trois remarques, olivieram :
    1. Du moment qu'on utilise split, on utilise les expressions régulières (mais je reconnais que c'est souvent sans importance, y compris ici, c'est juste pour dire).
    2. Additionner, pour chaque ligne, 50000 à "Date(8)" me semble d'une utilité discutable, vu qu'on obtient systématiquement pour résultat 50000, qu'on se prend un avertissement, et qu'on ne touche pas à la date, ce qui est quand même le but de la manœuvre..
    3. De plus, le but est d'avoir des résultats variés, pas des résultats systématiquement à année + 5.


    Je propose ceci (qui comporte une regex très optimisée, parce que très contrainte) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while(<STDIN>)
    {
      s/\b(\d{8})$/$1+(int(rand(5))+1)*(int(rand(2))-0.5)*2*10000/e;
      print;
    }
    Je sais, c'est pas super lisible. Je suis parti du principe que le résultat souhaité était qu'aucune date ne soit exacte. Si on n'a rien contre une date exacte de temps en temps, on peut faire plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while(<STDIN>)
    {
      s/\b(\d{8})$/$1+(int(rand(11))-5)*10000/e;
      print;
    }
    Mmmh, des boucles while avec juste deux lignes dont un print ? Oui, on peut en faire des unilignes.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    perl -lpe's/\b(\d{8})$/$1+(int(rand(5))+1)*(int(rand(2))-0.5)*2*10000/e' fichier
    perl -lpe's/\b(\d{8})$/$1+(int(rand(11))-5)*10000/e' fichier
    There's nothing like $HOME!

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Merci au fait pour comprehension que veut dire s/\b(\d???????
    En fait tu pourrais expliquez ou commentez ta ligne "s/\b(\d{8})$/$1+(int(rand(5))+1)*(int(rand(2))-0.5)*2*10000/e;" juste pour comprendre


    Merci tout le monde

  5. #5
    Membre confirmé
    Avatar de Schmorgluck
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    371
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2006
    Messages : 371
    Points : 558
    Points
    558
    Par défaut
    Au temps pour moi. Effectivement, non seulement tu débutes, et donc je devrais expliquer un peu mieux que ça, mais en plus, d'une façon générale, je devrais être plus clair. Je prends de mauvaises habitudes.

    Bienvenue dans le monde merveilleux de Perl, dieuyam. Entre autres particularités remarquables, ce langage intègre les expressions régulières au cœur de sa syntaxe, avec principalement trois commandes :
    1. L'opérateur de correspondance ("match" en anglais), noté généralement m//, qui permet de vérifier si oui ou non l'expression régulière qu'il contient correspond à la chaîne de caractère à laquelle on essaie de l'appliquer.
    2. L'opérateur de substitution ("substitution" en anglais), noté généralement s///, qui remplace, le cas échéant, la chaîne correspondant à l'expression régulière qui constitue son premier opérande, par la chaîne de caractère qui correspond à son deuxième opérande, dans la chaîne de caractère à laquelle on essaie de l'appliquer.
    3. La fonction native split, dont le premier paramètre est (généralement) une expression régulière et le second une chaîne, et qui retourne une liste correspondant à la chaîne découpée avec pour séparateur ce qui a été reconnu par l'expression régulière.


    On peut ajouter l'opérateur =~ qui sert à appliquer la commande m// ou la commande s// (opérande de droite) à une chaîne de caractère (opérande de gauche). Dans la pratique, on s'en sert beaucoup moins qu'on a tendance à s'y attendre quand on découvre le langage. Mais laissons cela pour le moment.

    Les précédentes descriptions sont très sommaires, et ne couvrent que les utilisations les plus basiques de ces commandes, qui sont pleines de subtilités permettant de les utiliser de manières très diverses, que je vais m'empresser de ne pas exposer ici, tant j'ai déjà matière à digressions.

    D'autre part, les opérateurs m// et s/// ont des facilités de notation qui sont très intéressantes quand elles sont bien utilisées. Mal utilisées, elle rendent le code imbitable - une remarque qui vaut pour beaucoup de facilités de notation existant en Perl. Pas qu'en Perl, d'ailleurs, mais en Perl il y en a beaucoup, et il faut savoir raison garder. Je m'éloigne du sujet d'origine, mais je crois que c'est une remarque très importante à communiquer à un perliste débutant : Perl a la réputation d'être un langage extrêmement cryptique. Cette réputation n'est pas totalement usurpée, mais elle est principalement due à des programmeurs peu soigneux - et peut-être en partie à des profanes effarés par des unilignes éventuellement (j'y reviendrai). Utiliser à outrance les facilités d'écriture de Perl, sans prêter suffisemment attention à la lisibilité du code, c'est ce que j'appelle personellement "l'ivresse de Perl". Je n'y suis pas immunisé moi-même.

    Et voilà, je suis parti dans une tirade sans même expliquer ce que je voulais dire par "facilités de notation". Alors voilà : on utilise la barre oblique, par défaut, pour délimiter les opérateurs m// et s///. Mais ça n'est pas la seule façon de les délimiter. On peut utiliser plein de trucs à la place des barres obliques. Des points d'exclamation. Des dièses. Des virgules. Des topinambours. Euh, non, pas des topinambours. Mais plein de trucs, vraiment (attention, on peut utiliser des points d'interrogation, mais ç'a une signification spéciale qui n'a plus tellement d'intérêt : à éviter). Et encore, là je n'ai évoqué que les signes solitaires. Les signes appariés, à savoir les crochets, les accolades, les parenthèses, et les signes inférieur et supérieur, peuvent être utilisés, mais alors il faut une paire dans le cas de m// et deux paires dans le cas de s//.
    Ça veut dire que m/tru?c/ est équivalent à
    • m!tru?c!
    • m,tru?c,
    • m#tru?c#
    • m<tru?c>
    • m{tru?c}
    • m[tru?c]
    • m(tru?c)

    et que s/tru?c/bidule/ est équivalent à
    • s!tru?c!bidule!
    • s,tru?c,bidule,
    • s#tru?c#bidule#
    • s<tru?c><bidule>
    • s{tru?c}{bidule}
    • s(tru?c)(bidule)


    Et là, la question qui vient tout de suite, c'est "à quoi ça sert ?" Et, comme souvent en Perl, la première réponse est "à ne pas se casser le tronc". En l'occurrence, à ne pas trop ce casser le tronc quand il y a besoin de barres obliques dans l'expression régulière (si on veut l'appliquer à une URL, un chemin XPath, un chemin de fichier - toutes ces choses à peu près identique entre elles, et incontournables). Ça n'est pas nécessairement la meilleure réponse. En tout cas, elle est incomplète. On peut utiliser ces notations alternatives pour éviter de se casser le tronc et rendre le code plus lisible, à condition de rester rigoureux et raisonnable. Et le résultat, chez les perlistes rigoureux et raisonnables, c'est qu'en définitive, quand les barres obliques sont génantes (mais pas seulement), on se rabat à peu près systématiquement sur les accolades, pour des tas de raisons plus ou moins rationnelles. Le fait que Perl est de la famille du C et que dans les langages de la famille du C, les accolades, ça fait "bloc", donc c'est lisible, est probablement à compter au nombre des explications les plus rationnelles. En fait, il n'y a pas besoin d'autre explication. Et puis c'est sympa, les accolades, c'est affectueux, convivial (désolé, il fallait vraiment que je la fasse, celle-là).

    Enfin c'est bien beau, mais les accolades c'est bien lisible quand il y a du code bien indenté et tout. Et commenté, c'est encore mieux. Mais une expression régulière, on ne peut pas l'indenter, ni la commenter. Elle doit être d'un bloc. C'est dommage.

    La mauvaise nouvelle, c'est que oui, en effet, c'est dommage. La bonne nouvelle, c'est que ça n'est pas vrai. Comment ça ça n'est pas vrai ? Ben non, ça n'est pas vrai. Grâce à qui ? Grâce à Perl ! En effet, en Perl, on peut indenter et commenter une expression régulière, en utilisant le modificateur /x (de même qu'on note par défaut m// et s///, on note par défaut les modificateurs d'expressions régulières comme ce x par /x, c'est une convention à retenir pour comprendre les tutoriaux et autres manuels). Cela nécessite d'échapper tous les caractères "blancs" (espaces, tabulations, etc), ce qui, dans l'écrasante majorité des cas, est un compromis parfaitement productif et totalement indolore.

    Et là, certains rétorqueraient "Mais, on peut faire ça aussi dans d'autres langages, expressions régulières indentées, commentées, et tout." Ben oui. Mais grâce à qui? Grâce à Perl ! Les autres ont piqué l'idée (presque tous les progrès des expressions régulières en programmation sont venus de Perl - j'ai bien dit presque), et c'est une bonne chose, d'ailleurs. On voit suffisemment de mauvaises idées circuler trop facilement pour se réjouir sans équivoque de voir les bonnes circuler aussi. C'est aussi ça, le Logiciel Libre.

    Il me reste deux remarques à faire avant de revenir au vif du sujet.
    D'abord, j'ai mentionné qu'avoir des barres obliques embarrassantes n'était pas la seule raison possible pour un programmeur Perl d'utiliser les accolades à la place. L'autre raison courante est justement le mode indenté. Là, on préfère en général utiliser des accolades, juste pour que la structure soit plus lisible.
    D'autre part, la commande m// a une particularité. Tant qu'on utilise des barres obliques comme délimiteurs, la lettre 'm' est totalement facultative. Et les programmeurs Perl étant une foutue bande de grosses feignasses, taper cette lettre facultative est au dessus de leurs forces, ou trop vil pour leur dignité, interprête-le à ta guise. Toujours est-il que tu trouveras beaucoup plus souvent (beaucoup beaucoup beaucoup beaucoup beaucoup plus souvent) /toto/ que m/toto/ dans du code Perl.

    Et là, PAF! J'en reviens au vif du sujet (après m'être relu pour comprendre où je voulais en venir initialement), pour mentionner une autre particularité cocasse de Perl, c'est celle de "variable par défaut". Cette variable s'appelle $_. Elle subit tout, elle encaisse tout, et tu n'as même pas besoin de l'appeler pour ça. Et si tu l'appelles, il se peut qu'elle arrive d'endroits inattendus. Dans mon esprit un tantinet fantasque, je l'appelle "variable Igor". Parmi les commandes qui requièrent au moins un paramètre ou un opérande, nombre sont celles qui, à défaut d'en avoir un fourni explicitement, se rabattent sur $_. Et c'est le cas de m// et s///. Et c'est d'ailleurs pour cela que l'opérateur =~ n'est pas utilisés si souvent que ça. La plupart du temps, Igor suffit à faire le boulot.

    Et c'est LÀ, LÀ, que je vais enfin expliquer où je veux en venir.

    D'abord, la façon dont j'ai utilisé s/// utilise $_ par défaut, initialisé par la boucle while.

    Ensuite, voici la version indentée et commentée de cette fameuse commande s/// :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    s{
      \b #une limite de mot. Par défaut, pour Perl, un "mot" est ce qui est constitué de caractères alphanumériques ou d'un caractère soulignié.
        (\d{8}) Exactement huit chiffres décimaux, capturés par une paire de parenthèses... capturantes.
      $  #fin d'entrée. En général, c'est une fin de ligne ou de fichier, mais d'autres cas d'espèce existent.
      }
      {
        $1+(int(rand(11))-5)*10000
      }ex; Le modificateur /x, on en a déjà parlé. Le modificateur /e indique que les fringues doivent être récuprées à tout pris et le plus vite possible
    There's nothing like $HOME!

Discussions similaires

  1. Maj automatique des textes dans Notepad++ depuis un autre fichier
    Par municipum dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 05/02/2014, 00h11
  2. Réponses: 6
    Dernier message: 07/06/2011, 11h00
  3. appel d un fichier dans plusieurs emplacement d un autre fichier
    Par arasm dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 20/08/2009, 17h38
  4. Réponses: 3
    Dernier message: 19/05/2009, 09h00
  5. Réponses: 1
    Dernier message: 20/08/2007, 10h25

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