Scripts et Programmation

PERL : Mémo pour scripter

Cet article a été mis à jour, vous consultez ici une archive de cet article!
Table des matières

Introduction




Je script, je script, mais parfois, j'ai un sacré trou de mémoire ... et je galère à trouver ce que je cherche sur Internet.

Comment on incrémente une variable ? Comment on fait un SI, un POUR ?

Et bien la réponse se trouve ci-dessous !



Rappels de base




Un script se rend exécutable, finit généralement par .pl

Code BASH :
vi script.pl


Code BASH :
chmod +x script.pl


La première ligne indiquant l'interpréteur est :

Code TEXT :
#! /usr/bin/perl


Dans tous mes scripts Perl, j'utilise :

Code BASH :
use strict;
use warnings;


Cela force l'initialisation propre des variables et permet d'être rigoureux dans le code.

Je rappelle aussi que toutes les lignes se terminent par un point-virgule, et que lorsqu'on affiche avec print une variable, il faut penser à effectuer le saut de ligne avec \n :

Code BASH :
print "Bonjour !\n";


Les variables




Affectation de variable




Il faut avant tout déclarer les variables avec my :

Code BASH :
my $a;


Pour mettre dans la variable a la valeur chaîne toto :

Code BASH :
$a="toto"


De la même façon, on peut mettre dans des variables des nombres :

Code BASH :
$a=42


Pour utiliser ces variables, ajouter un $ devant :

Code BASH :
print "$a\n;"
toto




Les Opérateurs




Les opérateurs de calcul




Si on veut faire une addition :

Code BASH :
$a+3


Si on veut faire une soustraction :

Code BASH :
$a-3


Si on veut faire une multiplication :

Code BASH :
$a*3


Si on veut faire une division :

Code BASH :
$a/3


Les opérateurs de chaines




Si on veut concaténer une variable avec une chaine :

Code BASH :
$b." chaine"


L'importance des guillemets




Code BASH :
my $un_fruit = "une pomme";


Code BASH :
print "Hier, j'ai mangé $un_fruit.\n";[/code]
Affichera [b]Hier j'ai mangé une pomme[/b]
 
[code=bashprint 'Hier, j\'ai mangé $un_fruit.\n';


Affichera Hier j'ai mangé $un_fruit

A noter que pour échapper un caractère c'est le symbole anti-slash.



Assigner, incrémenter, décrémenter




Plutôt que de faire un calcule complexe tel que

Code BASH :
$a=$a+2


on a des raccourcis pour faire des calculs sur la variable elle même :

Pour l'addition :

Code BASH :
$a += 2


Pour la soustraction :

Code BASH :
$a -= 2


Pour la multiplication :

Code BASH :
$a *= 2


Pour la division :

Code BASH :
$a /= 2


Pour incrémenter :

Code BASH :
$a++


Pour décrémenter :

Code BASH :
$a--


La répétition

Code BASH :
print "bla" x 10;




Les structures conditionnelles : If




Le test "Si'" est généralement fait ainsi :

Code BASH :
if (condition) {
    instructions;
}
else
{
    instructions;
}


Il est possible de faire ça en "oneliner" via :

Code BASH :
(condition) ? instruction si vrai : instruction si faux


Pour les exemples, nous avons besoin d'opérateurs de comparaison, voir ci-dessous.

Les opérateurs de comparaison




Comparaison d'entiers




== : est égal à

Code BASH :
if ( $a == $b )


!= : n'est pas égal à

Code BASH :
if ( $a != $b )


> : est plus grand que

Code BASH :
if ( $a > $b )


>= : est plus grand ou égal à

Code BASH :
if ( $a >= $b )


< : est plus petit que

Code BASH :
if ( $a < $b )


<= : est plus petit ou égal à

Code BASH :
if ( $a <= $b )


Comparaison de chaînes




eq : est égal à

Code BASH :
if ( "$a" eq "$b" )


ne : n'est pas égal à

Code BASH :
if ( "$a" ne "$b" )


Ensuite, on peut comparer par ordre alphabétique.

lt : inférieure à (située avant dans l'ordre alphabétique)

Code BASH :
if ( "$a" lt "$b" )


le : inférieure ou égale à (située avant dans l'ordre alphabétique)

Code BASH :
if ( "$a" le "$b" )


gt : supérieure à (située après dans l'ordre alphabétique)

Code BASH :
if ( "$a" gt "$b" )


ge : supérieure ou égale à (située après dans l'ordre alphabétique)

Code BASH :
if ( "$a" ge "$b" )


Opérateurs Logiques




|| : OU logique : (or semble fonctionner)

Code BASH :
((condition1)||(condition2))


&& : ET logique :

Code BASH :
((condition1)&&(condition2))


! : NON logique :

Code BASH :
((condition1)!(condition2))




Les structures conditionnelles Partie 2




If elsif else




Perl n'inclut pas de fonction Switch par défaut (il faut installer le module Switch pour ça).

On peut donc chainer les if avec des elsif :

Code BASH :
if (condition) {
    instructions;
}
elsif (condition) {
    instructions;
}
else (condition) {
    instructions;
}


unless (if inversé)




L'instruction unless est identique au if, c'est juste que ça exécute les instructions si la condition est fausse :

Code BASH :
unless (condition fausse) {
    instructions
}


For




Pour le for ce n'est pas très compliqué :

Code BASH :
for (compteur; condition; pas) {
    instructions
}


Voici un exemple simple :

Code BASH :
for ($i=1; $i<10; $i++) {
    print $i;
}


While




De manière générale, la syntaxe est la suivante :

Code BASH :
while (condition) {
    instructions
}


Voici un exemple :

Until (while inversé)




L'instruction until est identique au while, c'est juste que ça exécute les instructions si la condition est fausse :

Code BASH :
until (condition) {
    instructions
}


Les tableaux




Création




Pour créer un tableau, on utilise le symbole arobase pour le nommer :

Code BASH :
my @noms = ("pim","pam","poum");


Pour remplir un tableau de 1 à 20, on peut utiliser des raccourcis comme :

Code BASH :
@nombres = (1 .. 20);


Appel des valeurs




On peut appeler les éléments par leur numéro d'index (ça commence à zéro) :

Code BASH :
print "$noms[0]";


Ajouter et supprimer des éléments




On a à notre disposition 4 fonctions :

  • push(@tab, "Valeur") : Ajoute un élément à la fin du tableau
  • unshift(@tab, "Valeur") : Ajoute un élément au début du tableau
  • pop(@tab) : Supprime le dernier élément du tableau
  • shift(@tab) : Supprime le premier élément du tableau



Exemple :

Code BASH :
push(@noms, "adrien");
unshift(@noms, "adeline");
pop(@noms);
shift(@noms);


On peut aussi supprimer un élément bien précis du tableau en fonction de son nom :

Code BASH :
delete $tab[index]


Exemple de suppression du 4ème élément (index 3) :

Code BASH :
delete $noms[3];


Transformer une chaine en tableau et inversement




Si on a une chaine du style :

Code BASH :
$copains = "Adrien-Adeline-Mathieu-Marie-Nathalie-Elise";


Et qu'on veut créer un tableau d'après ça, on peut utiliser split :

Code BASH :
@tab = split('séparateur', $chaine);


Exemple :

Code BASH :
@noms = split('-',$copains);


Pour revenir à la chaine créée, on utilise join :

Code BASH :
$chaine = join('séparateur',@tab);


Exemple :

Code BASH :
$copains = join('-',@noms);


Le tri




Pour trier le tableau, par ordre alphabétique par exemple, on utilise sort :

Code BASH :
@tab= sort(@tab);


Longueur du tableau




Pour trouver la longueur d'un tableau, soit on peut utiliser le dernier élément du tableau et ajouter 1 :

Code TEXT :
$nb = $#tab + 1


Soit directement avec la variable tableau :

Code BASH :
$nb = @tab;


Si on appelle juste

Code TEXT :
print @tab;


ça affiche tout le tableau !

Les structures conditionnelles Partie 3




Foreach




La boucle foreach permet de parcourir une liste ou un tableau :

Code BASH :
foreach (LISTE) {
    instructions;
}


Exemple :

Code BASH :
foreach (@tableau) {
    print $_;
}




- Utiliser des arguments au script --



Avec le tableau des arguments




Tous les arguments passés sont récupérés dans le tableau @ARGV.

On peut afficher les arguments de cette manière :

Code BASH :
foreach (@ARGV)
{
    print $_."\n";
}


On peut récupérer le nombre d'arguments via

Code BASH :
$nb_args = @ARGV;


Voici comment récupérer les arguments :

Code BASH :
my $arg1 = $ARGV[0]; #premier argument
my $arg2 = $ARGV[1]; #deuxième argument


Ou mieux :

Code BASH :
my ($arg1, $arg2) = @ARGV;


Avec perl -s




Avec la méthode ci-dessus, c'est difficile de gérer les ordres si ce sont des options.

Voici une façon de faire (très rudimentaire mais qui peut être utile).

Prérequis : Appeler le script avec perl -s (Windows) ou #! /usr/bin/perl -s (Linux)

Voici comment déclarer des options :

Code BASH :
our $a; #ARG -a
our $b; #ARG -b
our $c; #ARG -c


Si on appelle le script de cette façon :

Code BASH :
script.pl -a -b=3 -c=adrien


Dans ce cas précis : La variable $a contient 1 , la variable $b contient 3 , la variable $c contient adrien.

Donc :

Si argument est présent, ça vaut 1 sinon, indéfini.

Si argument est présent et à une valeur : ça prend la valeur



Les fonctions




Il est possible de créer des fonctions grâce à "sub".

Il est préférable de les placer de préférence au début du programme (avant de l'appeler).

Code BASH :
sub affiche() {
    print "On affiche du texte depuis la fonction !\n";
}


Pour appeler la fonction dans le script :

Code BASH :
print "On va appeler la fonction affiche() :\n";
&affiche;
print "La fonction affiche a été appelée !\n";


Et si on veut créer une fonction pour laquelle on passe un paramètre et qui retourne quelque chose (ici exemple avec une fonction qui double un nombre) :

Code BASH :
sub doubler() {
    my $nb = $_[0]; #Premier argument du tableau des arguments
    $nb = $nb*2;
    return $nb;
}


Exemple d'utilisation (ce sera plus parlant) :

Code BASH :
print "On va afficher le double de 21 en appelant doubler(21) : ".&doubler(21)."\n";


Manipuler des fichiers




Pour définir un chemin de fichier dans une variable, c'est comme une chaine :

Code BASH :
my $fic='C:\Users\AZ\Desktop\fic.csv';


On va utiliser la fonction open :

Code BASH :
open (HANDLER, MODE, EXPR)


Un HANDLER (traduit littéralement Manieur) c'est une variable un peu spéciale qui représente le fichier qu'on va «manier». Le MODE c'est l'usage qu'on va en faire (lecture, écriture...). L'EXPRession c'est une chaîne qui contient le chemin d'accès au fichier.

On va faire simple avec quelques exemples.

Ouvrir un fichier en lecture seule.

Code BASH :
open ( HANDLER, "<", $fic ); # OU open ( HANDLER, $fic );
while ( <HANDLER> ) {
    chomp; # Supprime le saut de ligne
    print "$_\n";
}
close ( HANDLER );




Ouvrir un fichier en écriture. (Ecrase tout ce qu'il y a dedans et le créé si existe pas)

Code BASH :
open ( HANDLER, ">", $fic );
print HANDLER "Coucou!\n";
close ( HANDLER );




Ouvrir un fichier en écriture. (écrit à la fin si existe et le créé si existe pas)

Code BASH :
open ( HANDLER, ">>", $fic );
print HANDLER "Coucou ajouté!\n";
close ( HANDLER );


Ça match ?




La correspondance, avec match c'est un test un peu plus élaboré. Le match prend en compte des expressions régulières :

Code BASH :
my $var = "Toto";
if ( $var =~ /^T/ )
{
        print "La variable commence par \"T\" ! \n";
}




PERL et SQL




Intro




Je vais faire des exemples avec une base de données test, dont voici la structure :

Code SQL :
CREATE DATABASE test;
CREATE TABLE messages ( id INT(10) NOT NULL AUTO_INCREMENT, txt VARCHAR(64), PRIMARY KEY (id) );
INSERT INTO messages(txt) VALUES ('coucou');


On va avoir besoin des modules DBI et DBD::mysql :

Code BASH :
use DBI;
use DBD::mysql;


Pour définir par exemple ses variables ça se fait dans des chaines classiques :

Code BASH :
my $db="test";
my $dbhost="localhost";
my $dbport="3306";
my $dbuser="root";
my $dbpasswd="root";


On peut déclarer des variables qui nous serviront par la suite :

Code BASH :
my $db_handle;
my $sql;
my $statement;
my $result; 
my $row;
my $txt;


La connexion




Pour se connecter à la base :

Code BASH :
$db_handle = DBI->connect("dbi:mysql:database=$db;host=$dbhost:$dbport;user=$dbuser;password=$dbpasswd");


On peut se permettre aussi de se mettre en l'UTF8 par exemple :

Code BASH :
$statement = $db_handle->prepare("SET NAMES utf8;");
$statement->execute();




SELECT




Je pense que le petit bout de code sera plus parlant :

Code BASH :
$sql = "SELECT * FROM messages";
$statement = $db_handle->prepare($sql);
$statement->execute();
while ( $row = $statement->fetchrow_hashref()) {
    $result = "ID : $row->{id} - Texte : $row->{txt} ";
    print "$result\n";
}


On exécute la requête, et après on affiche chaque ligne retournée par le SELECT.

INSERT




Idem, bout de code parlant :

Code BASH :
$sql = "INSERT INTO messages(txt) VALUES (?)"; # On met des ? à la place des valeurs
$statement = $db_handle->prepare($sql);
$txt = "Wesh ça va?";
$statement->execute($txt); # On passe à execute les arguments




UPDATE




Code BASH :
$sql = "UPDATE messages SET txt='Comment ça va?' WHERE txt='Wesh ça va?'";
$statement = $db_handle->prepare($sql);
$statement->execute();


DELETE




Code BASH :
$sql = "DELETE FROM messages WHERE id>10";
$statement = $db_handle->prepare($sql);
$statement->execute();


La déconnexion




Code BASH :
$statement->finish;
$db_handle->disconnect();




Diverses fonctions




Switch




Le Switch permet d'effectuer une action en fonction d'un cas précis. Cela évite de mettre une infinité de si alors sinonsi alors sinonsi ...

Il faut par contre utiliser le module Switch

Code BASH :
use Switch;


Voici un exemple complet d'utilisation :

Code BASH :
my $var = "Bonjour";
switch($var){
   case 1            { print "La variable vaut 1" }
   case "a"          { print "La variable est a" }
   case [1..10,42]   { print "La variable est dans la liste" }
   case (\@tab)    { print "La variable est dans le tableau" }
   case /\w+/        { print "La variable correspond au pattern WORD" }
   else              { print "Cas par défaut audun cas ci-dessus ne correspond" }
}


Le Try Catch




Le try/Catch bien connu des développeurs permet de gérer une exception en cas d'erreur.

Pour l'utiliser il faut le module Try::Tiny !

Code BASH :
use Try::Tiny;


Voici un exemple où on gère avec une division par zéro :

Code BASH :
try {
    my $err = 5/0;
}
catch {
    print "Erreur Division par 0 impossible !\n";
}; #Bien penser au ;




Astuces diverses




Longueur d'une chaîne




Code BASH :
my $chaine = "coolympique";
my $longueur = length $chaine;
print "La chaine '$chaine' contient $longueur caractères.";
 


Récupérer une saisie au clavier




Voici un exemple concret :

Code BASH :
print "Comment vous appelez-vous ? ";
my $nom = <>; # Récupération du nom de l'utilisateur
chomp $nom;   # Retrait du saut de ligne
print "Bonjour, $nom !\n";
 




Test de variable définie




Code BASH :
my $v;
if ( defined $v ) {
    print "La variable \$v est définie !\n";
} else {
    print "La variable \$v n'est pas définie !\n";
}




Voici un exemple simple pour tester l'OS sur lequel le script s'exécute.

Sous Linux on utlise PERL normal, sous Windows on utilise Strawberry Perl.

Code BASH :
use Encode qw(encode decode);
my $os = $^O;
my $msg = "Bonjour à tous ! Est-ce que ça va bien ?";
if ( $os eq "MSWin32")
    {
        print "On utilise PERL sous Windows bouhhhhh !\n";
        $msg = encode( 'cp437' , $msg);
        print "$msg\n";
    }
    else
    {
        print "On utilise PERL sous Linux yeahhhhhh !\n";
        $msg = encode( 'utf-8' , $msg);
        print "$msg\n";
}


Recharger le programme sans le quitter




Voici une astuce pour relancer un programme par lui même :

Code BASH :
exec( $^X, $0);