[Perl] débutant chercher conseil
jojo
-
jojo -
jojo -
bonjour,
je suis complétement novice en programmation mais dans le cadre de mon travail j'ai besoin de manipuler des données dans des fichiers texte. Perl est bien adapté pour cela.
1ère Q: : que dois-je installé comme environnement perl ?
j'ai téléchargé activePerl mais j'ai des soucis avec l'archive récupérée. j'arrive pas à l'installer
2ème Q : mon besoin
je dois rechercher dans plusieurs fichiers dont le nom est différent
et par date (ex: 200612) et une chaîne de caractère s=1, s=2, s=3 etc... et compter le nombre de s=1, s=2 etc... et envoyer le résultat dans un fichier avec les infos
200612
s=1 xxx
s=2 xxx
etc...
merci pour vos conseils
jojo
je suis complétement novice en programmation mais dans le cadre de mon travail j'ai besoin de manipuler des données dans des fichiers texte. Perl est bien adapté pour cela.
1ère Q: : que dois-je installé comme environnement perl ?
j'ai téléchargé activePerl mais j'ai des soucis avec l'archive récupérée. j'arrive pas à l'installer
2ème Q : mon besoin
je dois rechercher dans plusieurs fichiers dont le nom est différent
et par date (ex: 200612) et une chaîne de caractère s=1, s=2, s=3 etc... et compter le nombre de s=1, s=2 etc... et envoyer le résultat dans un fichier avec les infos
200612
s=1 xxx
s=2 xxx
etc...
merci pour vos conseils
jojo
Configuration: Windows XP Internet Explorer 6.0
9 réponses
-
Salut,
d'abord on va traiter la 1ère question :-)
depuis quel site tu as téléchargé ActivePerl?
et comment tu te prends pour l'installation? -
Salut,
comme je ne connais pas le contenu de tes fichiers, j'ai imaginé cette situation (4 fichiers dans le répertoire /home/lami20j/jojo)
la commande cat affiche le contenu de chaque fichierlami20j@debian:~$ cat jojo/200610 s=1 s=2 s=3 s=2 s=3 s=3 lami20j@debian:~$ cat jojo/200611 s=1 s=2 s=3 s=1 s=2 s=3 s=2 s=1 s=2 lami20j@debian:~$ cat jojo/200612 s=1 s=2 s=3 s=1 s=2 s=3 s=1 s=2 s=3 s=2 s=3 s=4 s=4 s=3 lami20j@debian:~$ cat jojo/200701 s=4 s=5 s=6 s=1 s=2 s=3 s=2 s=3 $=3 s=5 s=5 s=5 s=5 s=5 s=5 s=5 s=5 s=5Le script va créer un fichier que je l'ai appellé jojo_resultat
Voici le script (je l'ai nommé jojo.pl)#!/usr/bin/perl # use warnings;use strict; use File::Basename; my (@fichiers,%h); my $rep="/home/lami20j/jojo"; opendir (REP,$rep) or die "E/S : $!\n"; open F_ECRIRE,">>jojo_resultat" or die "E/S : $!\n"; while (defined (my $fic = readdir(REP))){ push @fichiers,"$rep/$fic" unless $fic=~/^\./; } foreach my $fic(sort @fichiers){ open F_LIRE,"$fic" or warn "E/S : $!\n"; while(<F_LIRE>){ map { $h{$_}++ } my @t=$_=~/(s=\d+)/g; } print F_ECRIRE basename($fic),"\n"; print F_ECRIRE "$_ $h{$_}\n" foreach (sort keys %h); delete $h{$_} foreach (keys %h); }Et le résultatlami20j@debian:~$ perl jojo.pl lami20j@debian:~$ cat jojo_resultat 200610 s=1 1 s=2 2 s=3 3 200611 s=1 3 s=2 4 s=3 2 200612 s=1 3 s=2 4 s=3 5 s=4 2 200701 s=1 1 s=2 2 s=3 2 s=4 1 s=5 10 s=6 1
-
bonjour,
merci pour ta réponse, mais je comprend rien !
les recherches à faire sont sur des fichiers de log et j'ai effectivement 4 fichiers mais qui peuvent être à cheval de date, voilà pourquoi il faudrait part exemple avant de lancer le script
que je précise la date ex: année 2006 et mois 12
est-ce que les constantes existes en perl ?
maintenant à l'intérieur des fichiers, je peux trouver S=1 ou s=2 etc... qu'une fois part ligne, il faut donc rechercher cette chaîne dans toutes les lignes et compter pour l'écrire dans un fichier.
qu'est-ce que c'est les use ?
que veut dire @fichiers, %h c'est un tableau ? et %h
je comprend pas le while et foreach
merci bien je vois que tu maîtrise bien le sujet !
jojo
-
-
Salut,
j'aimerai bien savoir exactement ce que tu veux et si possible d'avoir un exemple de ce que contient tes fichiers (tu peux mettre sur cjoint.com)
s=1 xxx
que veux tu dire par xxx ?
maintenant à l'intérieur des fichiers, je peux trouver S=1 ou s=2 etc... qu'une fois part ligne
J'ai conçu le script d'une manière qu'il prendre en compte n'importe combien de couple par ligne , aucun, un ou plusieurs
je n'aime pas etc.
soit un peu plus précis.
ce soir je n'ai pas le temps, on verra ça demain
je vais t'expliquer ce que j'ai fait, mais je crois que tu dois commencer à lire un peu. tu peux commencer avec perlintro et https://perl.developpez.com/cours/-
bonsoir,
xxx c'est le nombre de fois trouvé
j'ai pas d'exemple chez moi, mais comme je l'ais dit c'est des fichiers de log pour être plus précis c'est une ligne par connexion
dans cette ligne il faut que je recherche une chaîne s= qui peut avoir comme valeur 1, 2, 3, 4 ,
et écrire le cumul dans un fichier résultat
merci
cdt
jojo
-
-
Re,
c'est exactement ce que fait le script (ne te laisse pas piegé par l'exemple que je l'ai donné, ça marche aussi s'il y a un seul couple s=N )
le résultat est écrit dans un seul fichier
le script traite tous le fichiers de répertoire
maintenant l'important c'est la sortie
tu veux avoir en sortie combien de fichiers, un pour chaque fichier log ou un seule fichier avec le formantnom_fichier1 s=1 xxx . . nom_fichier2 s=1 xxx . .
Tu veux traiter tous les fichiers de répertoire, ou un certain fichier à la demande?
En fonctionne de tes réponses je peux améliorer le script.
Je vais repondre à tes questions (c'est promis :-)), mais d'abord je dois savoir exactement ce que tu veux :-)) -
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question -
En fait tu veux un calcul total quelque soit le nombre de fichiers?
par exemple
dans fichier 1
s=1
s=2
s=1
.
dans fichier 2
s=1
s=1
s=2
Le resultat
s=1 4
s=2 2
c'est ça que tu veux? -
Salut,
voilà le script (ce que tu vois en gras c'est le code, le reste se sont des commentaires, il faut les lire, c'est pour toi que je les ai écrit :-))#!/usr/bin/perl # =pod on utilise les pragma strict pour imposer une certaine discipline la déclaration de variables avec my dans notre cas on utilise le pragma warnings pour l'affichage des warnings ce qui peux nous aider pour corriger les erreurs =cut use warnings;use strict; =pod J'utilise 3 variables @fichiers - c'est un tableau les éléments du tableau peuvent être lus avec $fichiers[0]....$fichiers[n-1] - pour un tableau avec n éléments %h - c'est un hash, ou hachage ou tableau associatif on préfére le plus court, donc hash hash c'est une variable spéciale, une structure de données semblable à un tableau Mais au lieu d'indexer les valeurs par nombre, on les cherche par nom les indices sont des chaînes uniques et on les appelle des clés On peut lire une valeur correspondant à une clé avec $h{"cle"} = "valeur" $rep c'est une variable scalaire qui contient le chemin vers le répertoire dans lequel on a les fichies log =cut my (@fichiers,%h); my $rep="/home/lami20j/jojo"; =pod opendir c'est une fonction qui perment de lire un répertoire =cut opendir (REP,$rep) or die "E/S : $!\n"; =pod open c'est une fonction qui permet d'ouvrie un canal de communication vers en fichier. il y a plusieurs modes d'établir le canal de communication : lecture, écriture, ajout, etc. dans notre cas on a ouvert le mode écriture (>) =cut open F_ECRIRE,">jojo_resultat" or die "E/S : $!\n"; =pod jusqu'ici on a préparé le terrain pour traitment tout ce que tu vois après while c'est le traitement de fichiers c'est parti... en premier temps je lit le répertoire et je stocke dans le tableau @fichiers le nom de fichiers auquel j'ajoute aussi le chemin sauf les fichiers qui commence avec . et .. Pourquoi . et .. ? . c'est le répertoire courant .. c'est le répertoire parent =cut while (defined (my $fic = readdir(REP))){ push @fichiers,"$rep/$fic" unless $fic=~/^\./; } =pod pour chaque fichier contenu dans @fichiers j'ouvre le fichier en lecture ou j'affiche un message ensuite tant que je n'atteint pas la fin de fichier pour chaque couple s=Nombre (s=1,s=2,.. seront les clés de notre hash) je compte combien de couple j'ai Exemple: on a 3 s=1 la clé est "s=1" et on a vu plus haut que la clé est unique donc au début la valeur qui correspond à la clé est indéfini(undef) A savoir que s'il la valeur est traité en tant que chaîne elle vaut la chaîne vide "" si est traité en tant que nombre elle vaut 0 ${"s=1"}=${"s=1"}+1 donc à la fin on aura ${"s=1"}=3 donc c'est comme ça que je compte les nombre de s=1,s=2,... /(s=\d+)/ig; c'est une expression régulière (regex) // se sont les délimiteurs de la regex les paranthèses permet la capture de motif trouvé dans la variable $1 s= c'est la chaîne littérale \d c'est une classe de caractère qui correspond à tout chiffre de 0 à 9 + c'est un quantificateur qui perment de reconnaître au minimum une chiffre i c'est un modificateur de regex qui permet à la regex d'être insensible à la casse donc la regex peut reconnaître s ou S =cut foreach my $fic(@fichiers){ open F_LIRE,"$fic" or warn "E/S : $!\n"; while(<F_LIRE>){ $h{$1}++ if /(s=\d+)/i; } } =pod j'écrit dans le fichier en utilisant le canal de communication (handle) qu'on a ouvert plus haut $_ represente la clé ( s=1,...) $h{$_} c'est la valeur ( le nombre de chaque s=N) sort c'est une fonction qui va trier les s=N keys %h c'est un tableau qui contient les clés de hash en bref la ligne de code on peut l'interpreté écrit dans le fichier résultat la clé et le nombre d'occurences pour chaque clé dans le tableau de clés qui soit trié =cut print F_ECRIRE "$_ $h{$_}\n" foreach (sort keys %h); __END__ Tout ce que tu vois entre les balises =pod =cut se sont de commentaires de même tout ce que tu vois après __END__ n'est pas lu par l'interpreteur perl Tu vois que je n'utilise plus le même code que dans le 1er script, puisque le résultat que tu demandes et bien plus facile que je croyais-
-
j'ai oublié il manque une précision
c'est la date sous sa forme 200701
parce que j'ai des rotate de fichier de log à 50mo et il se peut
que le fichier log contienne des dates de 200612 et 200701
dont si je veux extraire mes résultats et il faut que je précise la date recherchée.
même si je dois aller dans le script pour mettre la date recherchée ça me dérange pas.
merci
salut
-
-
Salut,
donc si je comprends bien, il faut calculer le nombre de s=1,... en fonction de la date
en ce cas j'aimerai bien que tu me montre quelques ligne de ton log pour pouvoir faire les modifications dans le script-
-
bonjour,
ça devient difficile d'échanger sur ce forum, le soir c'est quasi inaccessible.
j'ai fait un test ça marche ! super
j'ai juste déclaré la variable $fic au début parce que le répertoire contient bien d'autres fichiers.
my $fic="message_log*";
j'ai modifié my $fic après defined en $fic
while (defined ($fic = readdir(REP))){
c'est quoi defined ?
merci
salut -
-
-
Salut,
ça ne marche pas avec des valeurs décimales
et oui je me suis aperçu qu'il y avait des 0,xx 1,xx
que faire ?
Essaie de remplacer cette ligne
$h{$1}++ if /(s=\d+)/i;
avec celle ci$h{$1}++ if /(s=\d+[,.]?\d*)\s*/i;
ou avec celle ci (si tu as des entrées de genre .2 ou ,2)$h{$1}++ if /(s=(?:\d+(?:[,.]?\d*)?|\[,.]\d+))\s*/i;je n'est pas testé, j'ai écrit à la volée :-))
A toi de me dire si ça marche ou pas :-) -
-
bonsoir,
ça marche bien avec la première solution, j'ai pas testé la deuxième.
j'ai encore une question (voir plus haut) comment executer ce script en ayant au préalable précisé la date.
il faut que je recherche tout ce qui est 200612
ayant comme valeur s=
autre question comment rechercher une chaîne avec les mots
entrée
sortie
merci beaucoup
salut
-