Projet

Général

Profil

Perl script : extracting some columns from a .maple file » hz_colMaple.pl

Julien Troufflard, 12/03/2015 11:10

 
1
#!/usr/bin/perl
2
#!/usr/local/bin/perl
3
use strict;
4
use Math::Trig;
5
use English;
6
#####use Regexp::Common;#expressions regulieres; par exemples pour reconnaitre un entier $RE{num}{int} ou un reel $RE{num}{real}
7
use File::Basename;
8
#nom de ce script
9
my $NOM_PROG = basename $PROGRAM_NAME;
10
#expression reguliere pour reconnaitre un nombre reel (on aurait pu aussi utiliser le package Regexp::Common, mais a la date du 12/03/2015, ce package etait non disponible sur les machines linux de la salle de calcul)
11
my $format_reel = '[+-]?[\.]?\d+[\.]?\d*(?:[eE][+-]?\d*)?';
12

    
13

    
14

    
15
my $VERSION = '1.01';
16
#################################################################################################
17
#  script pour extraire des colonnes d un fichier .maple                                        #
18
#  version 1    : version initiale                                                              #
19
#  version 1.01 : introduction de la variable $format_reel au lieu d utiliser le package        #
20
#                 Regexp::Common (car non disponible sur linux a la date du 12/03/2015)         #
21
#################################################################################################
22

    
23

    
24

    
25

    
26

    
27

    
28

    
29

    
30

    
31

    
32

    
33

    
34

    
35

    
36
sub affichage_aide {
37
  use Text::Wrap;
38
  #config du package Text::Wrap
39
  $Text::Wrap::columns = 80;#le nombre de caracteres maximum par ligne sera egal a ($Text::Wrap::columns - 1) dans le cas ou utilise wrap
40

    
41
  #indentation pour l affichage de Usage 2
42
  my $indent_Usage2 = ""; $indent_Usage2 .= " " for(1 .. length("          > $NOM_PROG "));
43

    
44
  print "\n";
45
  print "-----------------------------------------------\n";
46
  print " script $NOM_PROG  (version 1.0)\n";
47
  print "-----------------------------------------------\n";
48
  print "\n";
49
  print "But : extraire une ou plusieurs colonnes d un fichier de sortie Herezh++\n";
50
  print "      au format maple\n";
51
  print "\n";
52
  print "Usage 1 : mode interactif\n";
53
  print "          > $NOM_PROG\n";
54
  print "Usage 2 : lancement avec arguments\n";
55
  print wrap("          ",$indent_Usage2, "> $NOM_PROG [-h|help] [-v] fmaple_ini no_col1 [no_col2 .. no_colN] [fmaple_new]\n");
56
  print "\n";
57
  print "Arguments :\n";
58
  print "     o fmaple_ini : fichier .maple original\n";
59
  print "     o no_col_1 [no_col2 .. no_colN] : liste des numeros de colonnes a extraire\n";
60
  print "                                       format : > nombre entier (exemple : 1)\n";
61
  print "                                                > plage de colonnes (exemple : 3-6)\n";
62
  print "     o [fmaple_new] : fichier de sortie (par defaut : affichage dans le terminal)\n";
63
  print "\n";
64
  print "Options :\n";
65
  print "   -v : affichage du numero de version\n";
66
  print "\n";
67
  print "Exemples avec arguments :\n";
68
  print "   o sortir les colonnes 1 4 et 6 7 8 9 du fichier calcul_princ.maple\n";
69
  print "     dans le fichier resu.txt :\n";
70
  print "       > $NOM_PROG calcul_princ.maple 1 4 6-9 resu.txt\n";
71
  print "   o sortir les colonnes 1 et 9 du fichier calcul_princ.maple\n";
72
  print "     dans le terminal :\n";
73
  print "       > $NOM_PROG calcul_princ.maple 1 9\n";
74
  print "\n";
75
  print "Auteur :\n";
76
  print "   TROUFFLARD Julien\n";
77
  print "       julien.troufflard\@univ-ubs.fr\n";
78
  print "       julien.troufflard\@free.fr\n";
79
  print "--------------------------------\n";
80
  exit;
81
}
82

    
83
#------------------------------------
84
#option -h ou -help => affichage de l aide
85
#------------------------------------
86
# rq : insensible a la casse
87
foreach my $arg (@ARGV) {
88
  if(($arg =~ /^-h$/i) or ($arg =~ /^-help$/i)) {
89
    affichage_aide();
90
  }
91
}
92

    
93
#------------------------------------
94
#option -v => affichage de la version
95
#------------------------------------
96
foreach my $arg (@ARGV) {
97
  if($arg eq '-v') {
98
    print "\n $NOM_PROG : version $VERSION\n\n";
99
    exit;
100
  }
101
}
102

    
103

    
104

    
105
#----------------------------------
106
#saisie du fichier maple original
107
#----------------------------------
108
my $fmaple_ini;
109
#cas avec arguments
110
if($#ARGV > -1) {$fmaple_ini = shift(@ARGV);}
111
#cas mode interactif
112
else {
113
  $fmaple_ini = -1;
114
  while($fmaple_ini eq '-1') {
115
    print "\nNom du fichier maple original ? ";
116
    $fmaple_ini = <STDIN>; chomp($fmaple_ini);
117
  }
118
}
119
#verif de l existence du fichier
120
(-e $fmaple_ini) or die "\nErreur (prog:$NOM_PROG) : fichier $fmaple_ini introuvable ...\n\n";
121
#verif de l ouverture
122
open(FIC, "<$fmaple_ini") or die "\nErreur (prog:$NOM_PROG) : impossible d ouvrir fichier $fmaple_ini ...\n\n"; close(FIC);
123

    
124

    
125
#----------------------------------
126
#saisie des numeros de colonnes
127
#----------------------------------
128
my @no_colonnes;
129
#cas avec arguments
130
if($#ARGV > -1) {
131
  foreach my $arg (@ARGV) {
132
    #cas d un numero de colonne simple
133
    push(@no_colonnes, $1) if($arg =~ /^(\d+)$/);
134
    #cas d une plage de colonnes
135
    push(@no_colonnes, ($1 .. $2)) if($arg =~ /^(\d+)-(\d+)$/);
136
  }
137
}
138
#cas mode interactif
139
else {
140
  print "\nSaisie de la liste des colonnes :\n";
141
  print "   - par de simples nombres entiers (exemple : 12)\n";
142
  print "   - par une plage de colonnes (exemple : 3-6)\n";
143
  print "    (taper liste pour afficher la liste actuelle)\n";
144
  my $choix = -1;
145
  SAISIE_COL:while() {
146
    print "  > saisie (f pour finir) : ";
147
    $choix = <STDIN>; chomp($choix);
148
    $choix =~ s/^\s+//; $choix =~ s/\s+$//;
149

    
150
    #on traite la saisie en separant par rapport aux espaces pour gerer le cas ou l utilisateur donne plusieurs saisies sur une meme ligne
151
    foreach my $val (split(/\s+/, $choix)) {
152
      #cas d un numero de colonne simple
153
      push(@no_colonnes, $1) if($val =~ /^(\d+)$/);
154
      #cas d une plage de colonnes
155
      push(@no_colonnes, ($1 .. $2)) if($val =~ /^(\d+)-(\d+)$/);
156
      #cas du mot liste => affichage de la liste actuelle
157
      print "  Liste actuelle :\n  @no_colonnes\n\n" if($val eq 'liste');
158
      #cas de la lettre f => fin de la saisie
159
      last SAISIE_COL if($val eq 'f');
160
    }
161
  }
162
}
163
#verif de la presence d au moins une colonne a extraire
164
($#no_colonnes > -1) or die "\nErreur (prog:$NOM_PROG) : aucun numero de colonne n a ete specifie ...\n\n";
165

    
166

    
167
#--------------------------
168
#verification des colonnes
169
#  methode : on regarde la premiere ligne de donnees du fichier original et on y verifie la presence des colonnes demandees
170
#
171
#  remarque : on aurait pu faire cette verif au moment de l ecriture des colonnes, mais en le faisant ici, on evite de creer
172
#             inutilement le nouveau fichier en cas de colonne absente
173
#--------------------------
174
my @colonnes_inexistantes;
175
open(FIC, "<$fmaple_ini");
176
while(<FIC>) {
177
  next if(/^\s*\#/);
178
  next if(not /^\s*$format_reel/);
179
  s/^\s+//; s/\s+$//;
180
  my @val = split(/\s+/, $_);
181
  foreach my $col (@no_colonnes) {
182
    push(@colonnes_inexistantes, $col) if(not defined($val[$col-1]));
183
  }
184
  last;
185
}
186
close(FIC);
187
#pas de colonnes absentes, sinon erreur
188
($#colonnes_inexistantes == -1) or die "\nErreur (prog:$NOM_PROG) : les colonnes suivantes n existent pas dans le fichier $fmaple_ini : @colonnes_inexistantes ...\n\n";
189

    
190

    
191
#-------------------------------------
192
#saisie du fichier eventuel de sortie
193
#-------------------------------------
194
# rq : en mode arguments  : le fichier de sortie sera ecrase automatiquement si il existe deja
195
#      en mode interactif : on demande a l utilisateur si il veut ecraser un fichier deja existant
196
my $fmaple_new = "";
197

    
198
#cas avec arguments
199
if($#ARGV > -1) {
200
  #on suppose que le fichier de sortie est le dernier argument, a moins que ce ne soit un numero de colonne
201
  $fmaple_new = $ARGV[$#ARGV] unless($ARGV[$#ARGV] =~ /^\d+$/ or $ARGV[$#ARGV] =~ /^\d+-\d+$/);
202
}
203
#cas mode interactif
204
else {
205
  print "\nSaisie du fichier de sortie (taper entree pour une sortie dans le terminal) :\n";
206
  print "     Nom du fichier a creer : ";
207
  $fmaple_new = <STDIN>; chomp($fmaple_new);
208

    
209
  #cas ou le fichier existe deja (on demande en boucle jusqu a ce que le nom ne corresponde pas a un fichier existant ou que l utilisateur veut bien effacer l existant)
210
  while() {
211
    last if(not -e $fmaple_new);#fin si le fichier n existe pas
212

    
213
    print "Le fichier de sortie $fmaple_new existe deja :\n";
214
    my $choix = -1;
215
    while($choix ne 'o' and $choix ne 'n') {
216
      print "  Voulez-vous l effacer ? (o/n) ";
217
      $choix = <STDIN>; chomp($choix);
218
    }
219
    last if($choix eq 'o');#fin si l utilisateur veut ecraser le fichier existant
220

    
221
    
222
    print "     Donner un autre nom de fichier : ";
223
    $fmaple_new = <STDIN>; chomp($fmaple_new);
224
  }
225
}
226

    
227
#Handle d affichage pour la commande print ...
228
my $Handle;
229
#...vers un fichier si il a ete defini
230
if($fmaple_new ne "") { open($Handle, ">$fmaple_new"); }
231
#sinon, vers le terminal
232
else { $Handle = *STDOUT; }
233

    
234

    
235
#-------------------------------------
236
#ecriture de l en-tete
237
#-------------------------------------
238
print $Handle "#Fichier original : $fmaple_ini\n";
239
print $Handle "#\n";
240
print $Handle "#Correspondance avec les colonnes du fichier original :\n";
241
for(my $i=1; $i<=($#no_colonnes + 1); $i++) {
242
  print $Handle "#  col $i => $no_colonnes[$i-1]\n";
243
}
244
print $Handle "#\n";
245
print $Handle "\n";
246

    
247
#-------------------------------------
248
#ecriture des colonnes
249
#-------------------------------------
250
open(FIC, "<$fmaple_ini");
251
while(<FIC>) {
252
  next if(/^\s*\#/);
253
  next if(not /^\s*$format_reel/);
254
  s/^\s+//; s/\s+$//;
255
  my @val = split(/\s+/, $_);
256
  print $Handle "$val[ $no_colonnes[0]-1 ]";
257
  for(my $i=1; $i<=$#no_colonnes; $i++) {
258
    print $Handle " $val[ $no_colonnes[$i]-1 ]";
259
  }
260
  print $Handle "\n";
261
}
262
close(FIC);
263

    
264

    
265
#fin du programme si l ecriture se fait dans le terminal
266
exit if(not defined($fmaple_new));
267
#fermeture du fichier
268
close($Handle);
269
print "\nLe fichier $fmaple_new a ete cree ...\n\n";
    (1-1/1)
    Redmine Appliance - Powered by TurnKey Linux