FAQ PerlConsultez toutes les FAQ

Nombre d'auteurs : 18, nombre de questions : 250, dernière mise à jour : 29 octobre 2015  Ajouter une question

 

Bienvenue sur la FAQ Perl. Cette FAQ a pour vocation de vous enseigner ou de vous faire revoir les notions élémentaires de ce fantastique langage. Perl est très utilisé dans différents domaines depuis la gestion système, le réseaux, l'administration de bases de données, le web (CGI), la bureautique, la conception d'interfaces graphiques ou des contextes scientifiques telle la bioinformatique. Nous espérons que cette FAQ vous sera d'une grande utilité.

Vous souhaitez participer à l'amélioration de cette FAQ, n'hésitez pas !! Commentez

Bonne lecture !


SommaireCodes sources utilesDes codes sourcesTerminal (5)
précédent sommaire suivant
 

Vous avez sans doute déjà rencontré un problème d'affichage d'accents sur une console DOS ou un terminal Linux.

Code perl : Sélectionner tout
1
2
3
4
5
6
7
#!/usr/bin/perl 
use strict; 
use Carp; 
use warnings; 
  
print "J'essaie d'utiliser des accents àéé\n"; 
print "Essayons les entrées-sorties : \n";
Code : Sélectionner tout
1
2
J'essaie d'utiliser des accents ÓÚÚ 
Essayons les entrÚes-sorties :
Pour palier à ce désagrément, le système de gestion des encodages de Perl est excellent, puissant et pratique, mais mal compris par pas mal de gens. Pour afficher les accents correctement sur la console DOS Windows, Il faut mettre stdout avec l'encodage correct, ou utiliser l'un des modules spécialisés. chcp permet de récupérer la codepage correcte. Sous Linux, c'est le même principe. À la place de chcp, nous utilisons locale charmap.

Premièrement, récupérons le codepage correct.

Code perl : Sélectionner tout
my ($codepage) = (`chcp` =~ m/:\s+(\d+)/);
Encodons ensuite toutes les sorties STDOUT, STDERR et même STDIN.

Code perl : Sélectionner tout
1
2
3
foreach my $h ( \*STDOUT, \*STDERR, \*STDIN ) { 
  binmode $h, ":encoding(cp$codepage)"; 
}
Je vous recommande de toujours créer vos scripts au mode utf8. Pour cela, vous devez configurer votre éditeur de texte. Exemple avec PSPAD, il vous suffit de choisir utf8 dans le menu "format". Votre script sera ainsi au format utf8. Ensuite, mettez en début de script :

Code perl : Sélectionner tout
use utf8;
Voilà, maintenant tout "print" avec accents sera correct dans votre console DOS. Voici un script qui résume les codent ci-dessus qu'on mettra dans une fonction.

Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/perl 
use strict; 
use Carp; 
use warnings; 
  
use utf8; 
  
ActiverAccentDOS(); 
  
print "J'essaie d'utiliser des accents àéé\n"; 
print "Essayons les entrées-sorties : \n"; 
  
sub ActiverAccentDOS { 
  my ($codepage) = ( `chcp` =~ m/:\s+(\d+)/ ); 
  foreach my $h ( \*STDOUT, \*STDERR, \*STDIN ) { 
    binmode $h, ":encoding(cp$codepage)"; 
  } 
}
Code : Sélectionner tout
1
2
J'essaie d'utiliser des accents àéé 
Essayons les entrées-sorties :
C'est quand même beaucoup mieux ! Cette fonction peut être mise dans un de vos modules et appelée en début de vos scripts.

Ce programme a tout de même un défaut, il n'est pas portable et ne fonctionnera que sous Windows. Modifions-le pour que la procédure sous fonctionnelle quelque soir l'OS.

Code perl : Sélectionner tout
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
#!/usr/bin/perl 
use strict; 
use Carp; 
use warnings; 
  
use utf8; 
  
ActiverAccents(); 
  
print "J'essaie d'utiliser des accents àéé\n"; 
print "Essayons les entrées-sorties : \n"; 
  
sub ActiverAccents { 
	my $encodage; 
	# Windows 
  	if ( lc($^O ) eq 'mswin32') { 
		eval { 
			my ($codepage) = ( `chcp` =~ m/:\s+(\d+)/ ); 
			$encodage = "cp$codepage"; 
			foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) { 
				binmode $h, ":encoding($encodage)"; 
			} 
		};	 
	} 
	else { 
		$encodage = `locale charmap`; 
		eval { 
			foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) { 
				binmode $h, ":encoding($encodage)"; 
			} 
		};	 
	} 
  return $encodage; 
}
Dans ce programme, nous vérifons si nous sommes sous Windows ou non. De plus, les commandes de récupération de l'encodage du terminal sont sous eval pour éviter les messages d'erreurs non attendus.

Si vous ne souhaitez pas appliquer la modification d'affichage à tout STDOUT, vous pouvez toujours utiliser le module Encode.

Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/perl 
use strict; 
use Carp; 
use warnings; 
  
use utf8; 
use Encode;  
  
my ($codepage) = ( `chcp` =~ m/:\s+(\d+)/ ); 
print encode("cp$codepage", "J'essaie d'utiliser des accents àéé\n"); 
print encode("cp$codepage", "Essayons les entrées-sorties : \n");
Si vous ne souhaitez pas utiliser le module utf8, il est toujours possible d'utiliser les codes hexa corrects. Faut-il encore s'en souvenir ! Cette solution est moins propre et maintenable, mais peut toujours être utile.

ü \x81 à \x85 è \x8A
é \x82 ç \x87 ï \x8B
â \x83 ê \x88 î \x8C
ä \x84 ë \x89 ... ...
Les informations de ce tableau ont été trouvées ici, ce qui nous donne :

Code perl : Sélectionner tout
1
2
3
4
5
6
7
#!/usr/bin/perl 
use strict; 
use Carp; 
use warnings; 
  
print "J'essaie d'utiliser des accents \x85\x82\x82\n"; 
print "Essayons les entr\x82es-sorties : \n";
Voilà, notez quand même que ce n'est pas très lisible !

Commentez

Mis à jour le 14 juillet 2009 djibril Jedai

Pour saisir un mot de passe de façon invisible sur une console DOS, linux ou unix, il y a un module Perl Term::ReadPassword .
Sous windows, l'auteur du module recommande d'utiliser le module Term::ReadPassword::Win32.

Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/perl 
use strict; 
use warnings; 
  
use Term::ReadPassword::Win32; 
  
# Faire deviner le mot de passe : perl 
while (1) { 
  my $password = read_password('Veuillez deviner le mot de passe : '); 
  redo unless defined $password; 
  if ($password eq 'perl') { 
    print "Bravo, c'est le bon.\n"; 
    last; 
  }  
  else { 
    print "Dommage!\n"; 
    redo; 
  } 
}
Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/perl 
use strict; 
use warnings; 
use Term::ReadPassword; 
  
# Faire deviner le mot de passe : perl 
while (1) { 
  my $password = read_password('Veuillez deviner le mot de passe : '); 
  redo unless defined $password; 
  if ($password eq 'perl') { 
    print "Bravo, c'est le bon.\n"; 
    last; 
  }  
  else { 
    print "Dommage!\n"; 
    redo; 
  } 
}

Mis à jour le 15 juin 2009 djibril

Pour afficher une barre de progression sur la console DOS, Linux ou Unix, il est possible de la créer soit même ou bien d'utiliser des modules existant. Nous allons vous donner 2 exemples.

  • Code conçu soit même

Code perl : Sélectionner tout
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package Progressbar; 
  
use strict; 
use warnings; 
  
# Constructor 
sub new { 
  my $proto = shift; 
  my %p = @_; 
  my $class = ref($proto) || $proto; 
  my $self  = 
    { 
     anim              => [ ref($p{anim}) eq 'ARRAY' ? @{$p{anim}} : qw(\\ | / -) ], 
     text              => $p{text}      || "", 
     max               => $p{max}       || 100, 
     size              => $p{size}      || 40, 
     value             => $p{init}      || 0, 
     display_count     => $p{verbose}   || 0, 
     animation         => $p{anim}      || 0, 
     fill_char         => $p{fill_char} || "#", 
     nb_filled         => 0, 
     last_size_printed => 0, 
  }; 
  $self->{step} = $self->{max} / $self->{size}; 
  
  bless ($self, $class); 
  return $self; 
} 
  
# Progress method 
sub inc { 
  my $self = shift; 
  
  my $nb_filled = int(($self->{value}++) / $self->{step}) + 1; 
  if ($self->{nb_filled} != $nb_filled || $nb_filled == $self->{size}) { 
    my $pb = sprintf ("$self->{text} [%-$self->{size}s]", 
                      $self->{fill_char} x $nb_filled); 
    $pb .= " ".$self->{anim}->[$nb_filled % @{$self->{anim}}] if $self->{animation}; 
    $pb .= sprintf " =/$self->{max}", $self->{value} if $self->{display_count}; 
    $pb .= "\r"; 
  
    print STDERR $pb; 
    $self->{last_size_printed} = length $pb; 
  } 
  $self->{nb_filled} = $nb_filled; 
} 
  
# Erase method 
sub erase { 
  my $self = shift; 
  
  my ($string) = @_; 
  
  print STDERR (" " x $self->{last_size_printed})."\r"; 
  print STDERR $string if defined $string; 
} 
  
# Reset/end method 
sub end { 
  my $self = shift; 
  
  $self->{value}     = 0; 
  $self->{nb_filled} = 0; 
  print STDERR "\n"; 
} 
  
1; 
  
__END__ 
  
=head1 NAME 
  
=head1 SYNOPSIS 
  
use Progressbar; 
  
my $pb = Progressbar->new(text => "Computing"); 
  
foreach (0 .. 99) { 
  # ... 
  $pb->inc; 
} 
$pb->erase("Process done"); 
$pb->end; # $pb can be re-used immediatly 
  
my $pb2 = Progressbar->new(text => "Working", anim => 1); 
my $pb3 = Progressbar->new(text => "Working", 
                                 max  => 1000, 
                                 size => 58, 
                                 init => 500, 
                                 verbose => 1, 
                                 anim => [qw(0 1 2 3 4 5 6 7 8 9)], 
                                 fill_char => "="); 
  
foreach (0 .. 99) { 
  # ... 
  $pb2->inc; 
} 
$pb2->end; 
  
foreach (500 .. 999) { 
  # ... 
  $pb3->inc; 
} 
$pb3->end; 
  
=head1 DESCRIPTION 
  
Prints a progress bar on STDERR using ASCII characters. 
  
=head1 BUGS 
  
No known bug.
Pour l'utiliser, créez un script test.pl par exemple

Code perl : Sélectionner tout
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
#!/usr/bin/perl 
  
use strict; 
use warnings; 
  
use lib "."; 
use Time::HiRes qw(sleep); 
  
use Progressbar; 
  
my $pb = Progressbar->new(text => "Computing"); 
  
foreach (0 .. 99) { 
  sleep(rand(0.1)); 
  $pb->inc; 
} 
$pb->erase("Process done"); 
$pb->end; # $pb can be re-used immediatly 
  
my $pb2 = Progressbar->new(text => "Working", anim => 1, verbose => 1); 
my $pb3 = Progressbar->new(text => "Working", 
                                 max  => 1000, 
                                 size => 58, 
                                 init => 500, 
                                 verbose => 1, 
                                 anim => [qw(0 1 2 3 4 5 6 7 8 9)], 
                                 fill_char => "="); 
  
foreach (0 .. 99) { 
  sleep(rand(0.1)); 
  $pb2->inc; 
} 
$pb2->end; 
  
foreach (500 .. 999) { 
  sleep(rand(0.02)); 
  $pb3->inc; 
} 
$pb3->end;




Code perl : Sélectionner tout
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 warnings; 
use strict; 
use Term::ProgressBar; 
use Time::HiRes qw(sleep); 
  
my $MaxValue = 100; 
my $barre_progression1 = Term::ProgressBar->new( 
    { name  => "[Computing] ", 
      count => $MaxValue, 
      ETA   => "linear", 
    } 
); 
foreach (0 .. $MaxValue) { 
  sleep(rand(0.1)); 
  $barre_progression1->update($_); 
} 
$barre_progression1->message("Process done"); 
  
my $barre_progression2 = Term::ProgressBar->new( 
    { name  => "[Working] ", 
      count => $MaxValue, 
    } 
); 
foreach (0 .. $MaxValue) { 
  sleep(rand(0.1)); 
  $barre_progression2->update($_); 
} 
$MaxValue = 1000; 
$barre_progression2->target($MaxValue); 
$barre_progression2->message('max: 1000'); 
foreach (0 .. $MaxValue) { 
  sleep(rand(0.01)); 
  $barre_progression2->update($_); 
} 
  
print "\nFini!";
L'utilisation d'une barre de progression peut être intéressant lorsque que vous lisez un très gros fichier. Ca vous permet de voir l'avancement de la lecture du fichier. Pour faire cela, il suffit de récupérer la taille du fichier via stat afin de créer sa barre de progression, puis au fur et à mesure de la lecture du fichier, de mettre à jour la barre avec la taille courante du fichier en cours de lecture.

Exemple :

Code perl : Sélectionner tout
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
#!/usr/bin/perl 
use warnings; 
use strict; 
  
use Term::ProgressBar; 
my $file     = 'mon_fichier.txt'; 
my $size_max = ( stat $file )[7]; 
my ( $compteur_modif, $progression_octet, $next_update ) = ( 0, 0, 0 ); 
my $barre_progression = Term::ProgressBar->new( 
    {   name  => "[Lecture $file] ", 
        count => $size_max, 
        ETA   => "linear", 
    } 
); 
  
open( my $fh, '<', $file ) or die "Impossible d'ouvrir le fichier $file\n"; 
while ( my $ligne = <$fh> ) { 
  
    # ... <=== on travaille sur la ligne 
    #bar 
    $progression_octet += length($ligne); 
    $next_update = $barre_progression->update($progression_octet) 
        if ( $progression_octet > $next_update 
        && $progression_octet < $size_max ); 
} 
close($fh); 
  
$barre_progression->update($size_max) if $size_max >= $next_update;

Mis à jour le 16 juin 2009 djibril Philou67430

Si vous avez besoin que l'utilisateur interagisse avec votre script, vous avez le choix de le faire via une interface graphique (Perl/Tk, gtk2, etc), ou via la console (DOS, Linux, Unix, ...).

Pour interagir via une console, on utilise généralement <STDIN>. C'est simple, mais lorsque l'on a plusieurs choix, on est obligé de faire plusieurs boucles afin de tester la validité du choix. De plus, il ne faut pas oublier de faire un chomp pour éliminer les retour chariots. Il existe une multitude de modules sur le CPAN nous facilitant grandement la vie. C'est le cas du module Term::UI.

Code perl : Sélectionner tout
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
#!/usr/bin/perl 
use warnings; 
use strict; 
  
use Term::UI; 
use Term::ReadLine; 
  
my $term    = Term::ReadLine->new('prompt'); 
my $reponse = $term->get_reply( 
  prompt  => 'Choisir un nombre : ', 
  choices => [ 'Choix 1', 'Choix 2', 'Choix 3', 'Aucun choix'], 
  default => 'Aucun choix', 
); 
  
print "Vous avez choisi : $reponse\n"; 
  
my $bool = $term->ask_yn( 
                        prompt => 'Aimez vous les cookies ?', 
                        default => 'n', 
                ); 
if ( $bool ) { 
  print "J'aime les cookies\n"; 
} 
else { 
  print "Je n'aime pas les cookies\n"; 
}
On obtient le résultat suivant :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
1> Choix 1 
  2> Choix 2 
  3> Choix 3 
  4> Aucun choix 
 
 
Choisir un nombre :  [4]: 7 
 
Invalid selection, please try again: [4] 2 
Vous avez choisi : Choix 2 
 
Aimez vous les cookies ? [y/N]: y 
J'aime les cookies
Via la méthode get_reply, vous pouvez simuler un QCM facilement et proprement. Et si vous souhaitez poser une question attendant une réponse yes or no, c'est encore plus simple avec la méthode ask_yn.

Pour en savoir plus, la documentation CPAN est à votre disposition.

Mis à jour le 1er octobre 2009 djibril

Lorsque vous souhaitez appeler vos scripts perl via une console DOS ou Linux (ou Unix), vous avez souvent besoin de passer des arguments. La manière classique pour les récupérer est d'utiliser la variable @ARGV. Sachez qu'il existe un module perl nous permettant de gérer ces arguments proprement et facilement. Ce module est de plus déjà installé dans le core de perl, c'est le module Getopt::Long. Voici un exemple de code nous permettant de taper en ligne de commande ceci :

Code : Sélectionner tout
perl script.pl -nom djibril -fichier "C:\repertoire\fichier.txt"
Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/perl 
use strict; 
use warnings; 
use Getopt::Long; 
  
my ( $nom, $fichier ) = (); 
GetOptions( 'nom=s' => \$nom, 'fichier=s' => \$fichier,); 
  
if ( defined $nom ) { 
  print "nom : $nom\n"; 
} 
if ( defined $fichier ) { 
  print "fichier : $fichier\n"; 
}
Code : Sélectionner tout
1
2
nom : djibril 
fichier : C:\repertoire\fichier.txt
Ce module est très complet, n'hésitez pas à lire la documentation officielle. Vous pouvez créer des alias, récupérer plusieurs arguments pour une même option, etc. Voici un dernier exemple pour la route !!

Code : Sélectionner tout
perl script.pl -name djibril -fichier "C:\repertoire\fichier.txt" -fichier "D:\repertoire\fichier2.txt" -numero 2 -v
Code perl : Sélectionner tout
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
#!/usr/bin/perl 
use strict; 
use warnings; 
use Getopt::Long; 
  
my ( $nom, @fichiers, $numero, $verbeux) = (); 
GetOptions(  
  'nom|name=s' => \$nom,      # name ou nom 
  'fichier=s'  => \@fichiers, # On peut avoir plusieurs fichiers 
  'numero=i'   => \$numero,   # i pour integer => on récupère un entier 
  'verbeux|v'  => \$verbeux,  # flag de type -v ou -verbeux ou --v ou --verbeux 
); 
  
if ( defined $nom ) { 
  print "nom : $nom\n"; 
} 
if ( defined $numero ) { 
  print "numero : $numero\n"; 
} 
if ( @fichiers ) { 
  print "fichiers : @fichiers\n"; 
} 
if ( $verbeux ) { 
  print "mode verbeux\n"; 
}
Code : Sélectionner tout
1
2
3
4
nom : djibril 
numero : 2 
fichiers : C:\repertoire\fichier.txt D:\repertoire\fichier2.txt 
mode verbeux
NB: Notez l'importance de protéger le chemin de vos fichiers par des guillemets, surtout s'il y a des espaces. Voilà, amusez vous bien !!

Mis à jour le 27 octobre 2009 djibril

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsable bénévole de la rubrique Perl : djibril -