Extraire les bonnes données

Extraire les bonnes données - Perl - Programmation

Marsh Posté le 28-03-2008 à 12:25:35    

Bonjour,
 
Je débute en perl et j'ai du mal avec les regexp...
 
Voila j'ai un fichier texte tkprof et je voudrais, à partir de celui-ci, créer un autre fichier contenant que les données qui me seront utiles pour les passer dans un excel par exemple.
 
Voici une partie du fichier texte tkprof que je peux avoir en entrée :
 
SELECT pl_group_def.sec_admin_ind
FROM
 pc_user_def , pl_group_def , pl_profile_group WHERE pc_user_def.user_id =:1
  AND pl_profile_group.profile_skey =pc_user_def.profile_skey AND
  pl_group_def.group_skey =pl_profile_group.group_skey AND
  pl_group_def.sec_admin_ind =1
 
 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.02       0.02          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      0.00       0.00          0          4          4           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      0.02       0.02          0          4          4           0
 
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 57

 
Dans ce fichier apparait toutes les requêtes passées (ici on en voit qu'une seule) avec des stats. Le but serait de récupérer chaque requête (SELECT, INSERT, DELETE, etc) et les stats concernant la colonne "elapsed" pour chacune d'entre elle.
J'y suis arrivé avec un script ksh mais je pense que perl est plus adapté pour cela mais j'ai beaucoup de mal...
 
On devrait obtenir ceci en sortie :
 
SELECT * FROM SYS.SESSION_ROLES WHERE ROLE = 'DBA'
~0.27~0.00~0.00~0.27
SELECT pc_user_def.password , pc_user_def.user_skey ,   pc_user_def.profile_skey , pc_user_def.first_name , pc_user_def.mi ,   pc_user_def.last_name , pc_user_def.active_ind FROM pc_user_def WHERE pc_user_def.user_id =:1
~0.47~0.00~0.00~0.47
BEGIN         HELIOS.SESSION_COMMENCER2( :0,:1,:2); END;
~0.03~0.73~0.00~0.76
SELECT TLS.LOGIN_UTILISATEUR || ' / '  || VSS.TERMINAL    FROM V_OSUSER2 VSS,SESSION_UTILISATEUR SSU,UTILISATEUR TLS  WHERE SSU.SESSION_ID   (+)   = VSS.SID  AND TLS.UTILISATEUR_ID (+)   = SSU.UTILISATEUR_ID
~0.45~0.09~3.38~3.92

 
 
 

Reply

Marsh Posté le 28-03-2008 à 12:25:35   

Reply

Marsh Posté le 28-03-2008 à 13:39:30    

Si tu ne nous explques pas comment sont séparées tes requêtes dans le fichier, ça va être dur de t'aider.

Reply

Marsh Posté le 28-03-2008 à 14:24:59    

Oui désolé voici un exemple un peu plus long :
 
 
SELECT pl_group_def.sec_admin_ind
FROM
 pc_user_def , pl_group_def , pl_profile_group WHERE pc_user_def.user_id =:1
  AND pl_profile_group.profile_skey =pc_user_def.profile_skey AND
  pl_group_def.group_skey =pl_profile_group.group_skey AND
  pl_group_def.sec_admin_ind =1
 
 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.02       0.02          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      0.00       0.00          0          4          4           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      0.02       0.02          0          4          4           0
 
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 57
 
Rows     Row Source Operation
-------  ---------------------------------------------------
      0  NESTED LOOPS
      2   NESTED LOOPS
      2    TABLE ACCESS BY INDEX ROWID PC_USER_DEF
      2     INDEX UNIQUE SCAN (object id 29602)
      2    TABLE ACCESS FULL PL_GROUP_DEF
      0   INDEX UNIQUE SCAN (object id 29626)
 
********************************************************************************
 
BEGIN          HELIOS.FONCTIONNALITE_LISTER2(:0,:result_set); END;
 
 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.02       0.02          0          0          0           0
Execute      1      0.54       0.64          0          0          2           1
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.56       0.66          0          0          2           1
 
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 57
********************************************************************************
 
SELECT USR.DESTINATION_ID,USR.LOGIN_UTILISATEUR,USR.UTILISATEUR_ID
FROM
 V_UTILISATEUR VTL,UTILISATEUR USR  WHERE USR.UTILISATEUR_ID =
  VTL.UTILISATEUR_ID
 
 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.28       0.22          0          0          0           0
Execute     92      0.00       0.00          0          0          0           0
Fetch       92      0.27       0.30          2        736          0          92
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total      185      0.55       0.52          2        736          0          92
 
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 57     (recursive depth: 1)

Reply

Marsh Posté le 31-03-2008 à 01:12:01    

Le pb est qu'il n'y a pas de chaines facile à analyser...
 
Je verrais bien un parsing à "états" :
1) les premières lignes non vides sont la requête sql (état 1)
2) la première ligne vide marque la fin de la requête sql (passe à l'état2)
3.a) la première ligne non vide suivante est l'entête du tableau, tu peux éventuellement repérer la position de la colonne elapsed en faisant un split + en cherchant la colonne
3.b) récupérer les valeurs dans la 4ème colonne (en skippant les lignes avec des ----
4) la ligne vide suivante fait passer l'état 3 (je skippe tout)
5) la ligne contenant des "******" fait revenir à l'état 1...
 
Un fois parsé, la réécriture ne devrait pas poser de pbs...
 
Bon courage...

Reply

Marsh Posté le 31-03-2008 à 17:48:55    

J'essayes de commencer par récupérer les différentes requetes pour les placer dans le fichier resultat.txt :
 

Code :
  1. my $requetes = qw( select alter insert delete update begin overall );
  2. open (F,"$rep/ora03380.txt" );
  3. open (Fsor,">$rep/resultat.txt" );
  4. while (<F> ){
  5. if ( /^$requetes/gi) {
  6.         print Fsor $1;
  7.     }
  8. }

 
 
Mon fichier resultat.txt reste vide. De plus je ne penses pas pouvoir récupérer chaque requête entierement comme cela...

Reply

Marsh Posté le 18-04-2008 à 12:47:16    

doog77 a écrit :

J'essayes de commencer par récupérer les différentes requetes pour les placer dans le fichier resultat.txt :
 

Code :
  1. my $requetes = qw( select alter insert delete update begin overall );
  2. open (F,"$rep/ora03380.txt" );
  3. open (Fsor,">$rep/resultat.txt" );
  4. while (<F> ){
  5. if ( /^$requetes/gi) {
  6.         print Fsor $1;
  7.     }
  8. }

 
 
Mon fichier resultat.txt reste vide. De plus je ne penses pas pouvoir récupérer chaque requête entierement comme cela...


Normal, vu que $requetes est une liste ici, et meme pas, puisque tu mets un contexte scalaire.
tu veux faire en fait quelque chose comme:
my @requetes = qw( select alter insert delete update begin overall );
my $pattern = "(";
$pattern .= join "|", @requetes;
$pattern .= " )";
.....
if ( /^$pattern/gi) {
        print Fsor $1;
}
 
A+,


Message édité par gilou le 18-04-2008 à 14:09:31

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 18-04-2008 à 15:10:08    

Tiens, j'ai pondu vite fait un script qui fait ce que tu veux, a toi de l'adapter a tes besoins spécifiques.
 

Code :
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;
  4. my @requetes = qw( select alter insert delete update begin overall );
  5. my $pattern = "(".(join "|", @requetes)." )";
  6. my @lines = qw( Parse Execute Fetch );
  7. my $pattern2 = "(".(join "|", @lines)." )";
  8. use constant SKIP  => 0;
  9. use constant QUERY => 1;
  10. my $state = SKIP;
  11. my @values;
  12. open F,"query.txt";
  13. while (<F> ){
  14.     if (/^\s*$pattern/oi) {
  15.         $state = QUERY;
  16.         print $_;
  17.         next;
  18.     }
  19.     elsif (/^\s*\n$/oi) {
  20.         $state = SKIP;
  21.         next;
  22.     }
  23.     if ($state == QUERY) {
  24.         print $_;
  25.         next;
  26.     }
  27.     ## a ce stade les queries sont traitees
  28.     if (/^\s*$pattern2/oi) {
  29.         s/\s+/ /g;
  30.         push @values, (split /\s/, $_)[3]; # 3 pour elapsed
  31.         next;
  32.     }
  33.     elsif (/^\s*total/oi) {
  34.         s/\s+/ /g;
  35.         push @values, (split /\s/, $_)[3]; # 3 pour elapsed
  36.         print "~", (join "~",@values), "\n";
  37.         undef @values;
  38.     }
  39. }
  40. close F;


 
A+,


Message édité par gilou le 18-04-2008 à 15:25:02

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed