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 sourcesQuelques unilignes perlTraitements de fichiers (19)
précédent sommaire suivant
 



Ce code vous permettra de convertir un fichier plat DOS en UNIX en convertissant les retours chariots vers le format unix. Cela permet de supprimer les ^M dans un fichier Mac par exemple. Cela est également pratique pour les fichiers transferés en FTP en mode binaire au lieu de ASCII. C'est léquivalent d'un dos2unix.

Code perl : Sélectionner tout
perl -pi.bak -e "s/\r\n/\n/" mon_fichier.txt
Ce code fait une sauvegarde préalable du fichier et supprime les ^M de mon_fichier.txt.

Code perl : Sélectionner tout
perl -pi -e "s/\r\n/\n/" mon_fichier.txt
Fait la même chose sans sauvegarde.

Mis à jour le 18 février 2011 djibril



Attention : bien qu'efficace, cette méthode est consommatrice de mémoire si vous l'appliquez sur un très gros fichier car ce dernier est entièrement chargé en mémoire.

Code perl : Sélectionner tout
perl -ne "print if ! $lignes{$_}++" mon_fichier.txt > nouveau_fichier.txt


Code perl : Sélectionner tout
perl -ne 'print if ! $lignes{$_}++' mon_fichier.txt > nouveau_fichier.txt

Mis à jour le 22 février 2011 djibril



Il peut être utilise d'avoir une petite commande perl permettant de modifier un mot dans un fichier. Cet uniligne est là pour ça. Dans l'exemple ci-dessous, nous changeons le nom de domaine yahoo.fr par developpez.com dans un fichier XML.

Code xml : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<annuaire> 
  <personne> 
    <nom>Philou</nom> 
    <prenom>Jean-Francois</prenom> 
    <telephone>01234567890</telephone> 
    <email>toto@yahoo.fr</email> 
  </personne> 
  <personne> 
    <nom>Dupont</nom> 
    <prenom>Paul</prenom> 
    <telephone>09876543210</telephone> 
    <email>titi@yahoo.fr</email> 
  </personne> 
</annuaire>
Code perl : Sélectionner tout
perl -pi.sauvegarde -e "s/yahoo\.fr/developpez\.com/g" annuaire.xml

Mis à jour le 22 février 2011 djibril

Code perl : Sélectionner tout
perl -ne "chomp; print join qq{ }, @{[ split /;/ ]}[8,0],$/" fichier.csv
Code perl : Sélectionner tout
perl -ne 'chomp; print join qq{ }, @{[ split /;/ ]}[8,0],$/' fichier.csv


Dans ce code, l'expression régulière du split constitue le séparateur de colonne du fichier d'entrée passé en paramètre (le retour à la ligne est considéré comme le séparateur de ligne). Les colonnes affichées dans l'exemple sont les colonnes d'indice 8 et 0, dans cet ordre. Elles sont affichées avec le paramètre du join comme séparateur.

Code csv : Sélectionner tout
1
2
col0;col1;col2;col3;col4;col5;col6;col7;col8;col9;col10 
test1;test2;test3;test4;test5;test6;test7;test8;test9;test10;test11
Code : Sélectionner tout
1
2
col8 col0 
test9 test1
Il est possible de raccourcir le code via les options -a -F et -l.

Code perl : Sélectionner tout
perl -laF';' -ne "print join q( ), @F[8,0]" fichier.csv
Code perl : Sélectionner tout
perl -laF';' -ne 'print join qq( ), @F[8,0]' fichier.csv
Ce code correspond à un code perl complet suivant :

Code perl : Sélectionner tout
1
2
3
4
5
6
7
#!/usr/bin/perl 
$\ = $/;                            # option -l 
while (<>) {                        # option -n 
  chomp $_;                         # options -l et -n 
  @F = split /;/;                   # option -a et -F 
  print join qq( ), @F[8,0];        # option -e 
}

Mis à jour le 22 février 2011 djibril lennelei Philou67430



Code perl : Sélectionner tout
perl -e "print scalar reverse <>" fichier

Mis à jour le 22 février 2011 djibril

Voici une solution minimale qui marche pour compter le nombre de mots (marche sous Unix ; sous Windows, remplacez les apostrophes par des guillemets) :

Code perl : Sélectionner tout
$ perl -e '$_ = shift; $wc = split; print qq/$wc\n/;' "ma phrase à compter"
Code : Sélectionner tout
1
2
 
4
Et une solution plus complète comptant les mots et les phrases:

Code perl : Sélectionner tout
>perl -e "$_ =shift; $wc = split /\s/; $pc = split /[\.\?\!]/; print qq/ $wc mots\n $pc phrases\n/;" "ma phrase à compter. Ma deuxième phrase. Une autre ? Ok :-) !  Merci."
Code : Sélectionner tout
1
2
 15 mots 
 5 phrases
Version avec un echo et un pipe (donc, sous Unix uniquement):

Code perl : Sélectionner tout
$ echo "les poules du couvent couvent." | perl -ne '$wc = split; print $wc, " mots \n";'
Code : Sélectionner tout
5 mots
Compter le nombre de mots pour chaque ligne d'un fichier, ici le fichier "essai.txt" (marche sous Unix, marche sous Windows toujours en remplaçant les apostrophes par des guillemets):

Code perl : Sélectionner tout
$ perl -ne '$wc = split; print qq/$. :  $wc \n/;' essai.txt
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
 
1 :  12 
2 :  12 
3 :  11 
4 :  14 
5 :  4 
6 :  5 
7 :  0 
...

Mis à jour le 16 juin 2012 Lolo78

Chapitre : unilignes
Testé sous :Linux, HP-UX, VMS, Windows (MS-DOS)

Cette commande remplace les tirets par des slash dans le fichier (sans création d'un fichier temporaire intermédiaire) et fait donc passer les dates du format 13-09-2010 au format 13/09/2010 :

Code perl : Sélectionner tout
perl -pi -e 's/-/\//g;' fichier.txt
Cette commande fait passer toutes les dates de tous les fichiers *.CSV en entrée du format 13/09/2010 au format 2010-09-13 :

Code perl : Sélectionner tout
perl -pi -e 's/;(\d\d)\/(\d\d)\/(\d{4})/;$3-$2-$1/g' *.csv
Remarque : Sous DOS, le *.csv n'est pas interprété correctement, il faut sans doute traiter chaque fichier individuellement, ou utiliser la syntaxe proposée par Alek-C :

Code perl : Sélectionner tout
FOR %A IN (*.CSV) DO perl -pi.bak -e "s/;(\d\d)\/(\d\d)\/(\d{4})/;$3-$2-$1/g" %A
Cette commande fait passer toutes les dates de tous les fichiers *.txt en entrée du format ?2000-10-16 17:12:23? au format ?16/10/2000?:

Code perl : Sélectionner tout
perl -pi -e 's/;(\d{4})-(\d\d)-(\d\d) \d\d:\d\d:\d\d/;$3\/$2\/$1/g' *.txt
Même remarque que précédemment sous DOS.

N.B. Pour les soucis d'interprétation de l'étoile * dans les terminaux DOS, il existe une astuce pour que votre terminal DOS le comprenne à travers Perl. Lisez cette QR.

Mis à jour le 26 juillet 2012 Lolo78

Chapitre : unilignes

Testé sous : HP-UX, Linux.

Commande Perl qui met en minuscules tous les noms de fichiers du répertoire courant:

Code perl : Sélectionner tout
perl -e 'for (@ARGV) { rename $_, lc($_) unless -e lc($_); }' *
Et pour mettre en majuscules les noms de fichiers commençant par « ad_ » dans le répertoire courant:

Code perl : Sélectionner tout
perl -e 'for (@ARGV) { rename $_, uc($_) unless -e uc($_); }' ad_*

Mis à jour le 26 juillet 2012 Lolo78

Chapitres : uniligne
Testé sous : Linux, Windows

La commande suivante permet de compter pour chaque ligne le nombre d'occurrences d'un motif donné... Il y a peut être plus simple (avec ou sans Perl), mais je n'ai trouvé que ça rapidement.
Dans mon cas, je voulais vérifier le nombre de pipe pour chaque ligne d'un fichier (en utilisant un petit | uniq après la commande suivante) :

Code perl : Sélectionner tout
> perl -ne "printf qq|%d\n|,$m=()=$_=~m/\|/g;" <fichier>
printf réalise un print formaté
qq|...| permet d'éviter l'utilisation des " parfois problématiques sous Windows ou dans les alias. Cette commande est équivalente à "..."
%d\n indique à printf d'afficher le premier argument au format décimal suivi d'un saut à la ligne
$m=()=m/\|/g; le secret, c'est l'assignation de l'expression m/\|/g à une liste anonyme () qui renvoie donc la liste des occurrences pour chaque ligne; puis, l'évaluation de cette liste dans un context scalaire avec $m=... qui provoque l'évaluation du nombre d'éléments de la liste.
Voir ici pour plus de détails et d'autre opérateurs sympas

N.B. \| est ici la chaîne cherchée, on peut évidemment la remplacer...

Mis à jour le 26 juillet 2012 lennelei

Chapitre : unilignes

Testé sous : HP-UX, Linux, VMS, MS-DOS.

J'avais un programme perl traitant un très gros fichier. À un moment donné, j'ai le message d'erreur suivant :

Code : Sélectionner tout
utilisation de valeur non initialisée à la ligne 2501743 du fichier.
Comment retrouver cette ligne pour comprendre la source de l'erreur ?

Code perl : Sélectionner tout
perl -n -e "{$i++; print $_ if $i == 2501743;}" nom_fichier.txt
Autre version plus compacte et sans doute un peu plus rapide :

Code perl : Sélectionner tout
perl -ne "print $_ if $. == 2501743;" nom_fichier.txt
Version encore plus compacte utilisant la variable par défaut $_ de print :

Code perl : Sélectionner tout
perl -ne "print if $. == 2501743" nom_fichier.txt
Autre version plus compacte pour imprimer les lignes N° 20 à 60 d'un fichier :

Code perl : Sélectionner tout
perl -ne "print if 20 .. 60" nom_fichier.txt
Même syntaxe pour n'imprimer qu'une seule ligne :

Code perl : Sélectionner tout
perl -ne "print if 30..30" nom_fichier.txt
Si le fichier est beaucoup plus gros que 2501743 lignes, la commande Perl suivante sera beaucoup plus rapide que les précédentes parce qu'elle abandonnera la recherche dès que la ligne est affichée :

Code perl : Sélectionner tout
perl -ne "print and exit if $. == 2501743;}" nom_fichier.txt

Commande qui affiche le numéro de ligne au début de chaque ligne d'un fichier, séparé du reste de la ligne par un espace :

Code perl : Sélectionner tout
perl -n -e "print qq/$. $_/"  file_in

Mis à jour le 26 juillet 2012 Lolo78

Testé sous : HP-UX, Linux (mais doit aussi marcher sous Windows et VMS en remplaçant les apostrophes par des guillemets).

Imprime le quatrième mot de chaque ligne, sauf si la ligne commence par un #, le séparateur entre les mots étant le ";" :

Code perl : Sélectionner tout
perl -naF";" -e 'next if /^#/; print qq/$F[3]\n/' fichier.txt
Imprime le cinquième et le deuxième mot de chaque ligne, séparés par un espace, sauf si la ligne commence par un # ou par un nombre quelconque d'espaces suivis d'un # (le séparateur étant toujours le ";") :

Code perl : Sélectionner tout
perl -naF";" -e 'print qq/$F[4] $F[1]\n/ unless /^ *#/' fichier.txt
Commande qui enlève le dernier champ d'un fichier, à condition qu'il n'y ait pas de ";" à la fin de ce dernier champ (en fait, on veut supprimer tout ce qui suit le dernier ";")

Le fichier exemple en entrée:

Code : Sélectionner tout
1
2
3
4
5
114280099;0.0.0.1 /account 2034354645;1;0; 
114280193;0.0.0.1 /account 2034360011;1;0;[[54 
114280220;0.0.0.1 /account 2034362388;1;0; 
117805929;0.0.0.1 /account 8451327160;1;0;[[51 
...
On veut supprimer le dernier champ (par exemple "[[54") quand il existe, en utilisant cette fois une expression régulière "gourmande" qui garde tout ce qui précède le dernier ";", celui-ci compris.

Code perl : Sélectionner tout
perl -ne '/(.*;)/; print qq/$1\n/' compte.txt > output.txt

Mis à jour le 25 août 2012 Lolo78

Testé sous : HP-UX et Linux (ainsi que VMS et Windows en remplaçant les apostrophes par des guillemets).

Pour retirer d'un fichier toutes les lignes vides ou ne comprenant que des espaces blancs :

Code perl : Sélectionner tout
perl -ne 'print unless /^\s*$/;' mon_fichier.txt > fichier_resultat.txt

Mis à jour le 25 août 2012 Lolo78

Testé sous : HP-UX, Linux (ainsi que VMS en remplaçant les apostrophes par des guillemets).

J'ai un programme qui compare les données clients entre deux applications différentes. L'une des séries de fichiers de sortie contient la liste des numéros de clients pour lesquels il y a des différences. La nature du traitement de comparaison garantit que les numéros de clients sont triés dans l'ordre ascendant, mais si plusieurs différences ont été trouvées, alors le numéro de client se trouve plusieurs fois à la suite. Je désire créer un fichier sans doublons.

Commande Perl qui lit le fichier (préalablement trié) file_in.txt et stocke le résultat dédoublonné dans file_out.txt :

Code perl : Sélectionner tout
perl -ne 'print $_ if $a ne $_; $a=$_;' file_in.txt > file_out.txt
L'option -i de la ligne de commande Perl permet de modifier directement le fichier en entrée (modification ?sur place?, sans création d'un second fichier).

Commande Perl qui dédoublonne tous les fichiers DELTA_*.TXT d'un répertoire (cette version avec variable d'environnement Unix ne marchera que sous Unix ou Linux, une retouche est nécessaire sous VMS) :

Code perl : Sélectionner tout
perl -ni -e 'print if $a ne $_; $a=$_;'  $RESULT_PATH/DELTA_*.TXT
Au fait, à propos d'ordre de tri: commande Perl qui lit le fichier file_in.txt et vérifie que chaque ligne est classée dans un ordre croissant et affiche à l'écran les lignes dans le désordre :

Code perl : Sélectionner tout
perl -ne 'chomp; print "$_ $a\n" if $a gt $_; $a=$_;' file_in.txt
On peut aussi faire un sort sur le fichier, mais ça peut être plus long avec un gros fichier. Cette commande peut aussi servir de test pour vérifier qu'un fichier est conforme aux spécifications.

Si le fichier est très gros, on peut se contenter d'arrêter la recherche dès la première anomalie rencontrée et afficher les deux lignes fautives ainsi que le numéro de ligne :

Code perl : Sélectionner tout
perl -ne 'print "$. $_ $a\n" and exit if $a gt $_; $a=$_;' file_in.txt

Mis à jour le 25 août 2012 Lolo78

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 -