Alignement des mots [Résolu]

Messages postés
273
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
31 août 2019
- - Dernière réponse : artagon7
Messages postés
273
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
31 août 2019
- 18 juin 2019 à 17:20
Bonjour,

J'ai un fichier texte dans lequel se trouve un item LaTeX à chaque ligne.

Par exemple, soit le fichier entree.txt :

\item [] abricot
\item [] banane
\item [] cerise
\item [] citron
\item [] poire
\item [] pomme


Au lieu, d'avoir un seul item par ligne, j'aimerais que le fichier comporte trois items par ligne. Ainsi, j'aimerais avoir le résultat suivant :

\item [] abricot   ************       \item [] banane      ***************        \item [] cerise
\item [] citron ************* \item [] poire **************** \item [] pomme


avec les termes \item alignés. Ici, j'ai dû employer des astérisques pour avoir l'affichage désiré.

Je voudrais connaître les lignes de commande que je dois utiliser.

Merci
Afficher la suite 

3 réponses

Meilleure réponse
Messages postés
5251
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 octobre 2019
806
1
Merci
Salut artagon7,

Il n'y a pas de "ligne de commande" particulière.

Une façon de faire, est d'utiliser les regexp pour capturer les item trois par trois et les afficher de façon formatée avec
printf
justifiés à gauche et avec la largeur minimale nécessaire déterminée (en prenant comme hypothèse que tu connais la largeur à utiliser).

Par exemple :

#!/usr/bin/perl

use strict;
use warnings;

my $st;

# simulation de l'ouverture d'un fichier et récupération
# des données de celui-ci dans une variable
{
    local $/;
    $st = <DATA>;
}

# traitement par paquet de trois lignes \item
while ($st =~ m/(\\item\s\[\]\s[^\s]+)\s(\\item\s\[\]\s[^\s]+)\s(\\item\s\[\]\s[^\s]+)/sg) {
    chomp $1;
    chomp $2;
    chomp $3;
    printf("%-20s%-20s%-20s\n", $1, $2, $3);
}

__DATA__
\item [] abricot
\item [] banane
\item [] cerise
\item [] citron
\item [] poire
\item [] pomme

donne à l'exécution :

$ ./36073873.pl 
\item [] abricot    \item [] banane     \item [] cerise     
\item [] citron     \item [] poire      \item [] pomme      
$ 

Les modificateurs sg à droite du slash fermant de la regexp permettent, respectivement, de matcher le contenu sur plusieurs lignes comme si tu n'en avais qu'une seule et de matcher toutes les occurrences au lieu de s'arrêter à la première.

Dans le
printf
, "%-20s" signifie affiche la chaîne correspondante à cet endroit, justifiée à gauche (signe moins), sur une largeur d'au moins 20 caractères en comblant les caractères manquants par des espaces. Le
printf
de Perl fonctionne de la même manière qu'en langage C (cette syntaxe du spécificateur est issue du C).

Si tu ne connais pas à l'avance l'espace minimal à utiliser ou si tu n'as pas un multiple de trois items, c'est plus compliqué.

Dal

Dire « Merci » 1

Heureux de vous avoir aidé ! Vous nous appréciez ? Donnez votre avis sur nous ! Evaluez CommentCaMarche

CCM 64120 internautes nous ont dit merci ce mois-ci

artagon7
Messages postés
273
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
31 août 2019
6 -
Salut Dal,

Je vais essayer ton programme et revenir avec les résultats.

Merci beaucoup.
Commenter la réponse de [Dal]
Messages postés
273
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
31 août 2019
6
1
Merci
Salut,

Le programme fonctionne. J'avais fait une erreur. On doit utiliser printf au lieu de print.

J'ai apporté une petite modification: au lieu de mettre trois items par ligne, le programme en met quatre.

Comme Dal l'a souligné dans l'une de ses réponses, le fichier doit contenir un nombre de lignes qui est multiple de 4, dans ce cas-ci, sinon les derniers mots du fichier ne seront pas considérés.

#!/usr/bin/perl 

use strict; 
use warnings; 

my $st; 

open (FICHIER_ENTREE, "fruits.txt"); 
open (FICHIER_ITEM, ">fruits_4.txt");

{
    local $/;
    $st = <FICHIER_ENTREE>;
}

while ($st =~ m/(\\item\s\[\]\s[^\s]+)\s(\\item\s\[\]\s[^\s]+)\s(\\item\s\[\]\s[^\s]+)\s(\\item\s\[\]\s[^\s]+)/sg) 
{
chomp $1; 
chomp $2; 
chomp $3; 
chomp $4; 
{printf FICHIER_ITEM "%-24s%-24s%-24s%-23s\n", $1, $2, $3, $4;} 
} 

close FICHIER_ENTREE; 
close FICHIER_ITEM; 


Merci

Dire « Merci » 1

Heureux de vous avoir aidé ! Vous nous appréciez ? Donnez votre avis sur nous ! Evaluez CommentCaMarche

CCM 64120 internautes nous ont dit merci ce mois-ci

Commenter la réponse de artagon7
Messages postés
273
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
31 août 2019
6
0
Merci
Salut Dal,

Ton programme fonctionne.

Mais, je veux le modifier pour inclure des fichiers.

J'ai modifié ton programme mais ça ne fonctionne pas.

Remarque que j'ai écrit ce message de mon téléphone et que ce dernier ne contient pas tous les symboles (signe plus petit, signe plus grand, accolade, backslash).

De plus, je n'ai pas réussi à le mettre en code.

Si ce n'est pas assez clair, je vais revenir lundi. Je vais être en moyen d'utiliser un ordinateur.
-------------------------------

#!/usr/bin/perl

use strict;
use warnings;

my $st;

$st = signe ppetit FICHIER_ENTREE signe pgrand ;

open (FICHIER_ENTREE, "fruits.txt");
open (FICHIER_ITEM, "€fruit_3.txt"); € = signe plus grand

while ($st ...) la ligne que tu as utilisée

@ accolade début

chomp $1;
chomp $2;
chomp $3;

¥ accolade début
print FICHIER_ITEM "%-20s%-20s%-20s£n", $1, $2, $3; £== backslash
¥ accolade fin

@ accolade fin

close FICHIER_ENTREE;
close FICHIER_ITEM;

-----------------------------

Deux messages d'erreurs:

1) readline () on unopened filehand FICHIER_ENTREE

2) Use of uninitialized value $st in pattern match (m//)

Merci,
[Dal]
Messages postés
5251
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 octobre 2019
806 -
Dans mon exemple
<DATA> 
est un filehandle spécial qui n'a pas besoin d'être ouvert en lecture et qui permet de lire les données embarquées dans le source du fichier dans la section
__DATA__
en fin de fichier source. C'est un moyen pratique de faire un exemple de code source fonctionnel simulant l'ouverture d'un fichier avec les données qu'il contient dans un code autosuffisant.

Dans ton cas, tu dois (1) ouvrir le fichier en lecture comme tu as l'habitude de le faire, puis (2) récupérer les données qu'il contient dans une variable en utilisant un code similaire à celui en lignes 10 à 13 de mon exemple en remplaçant DATA par le filehandle du fichier préalablement ouvert en lecture et (3) fermer le fichier.

Les deux erreurs que tu mentionnes ne devraient alors plus se produire, puisque tu auras ouvert le fichier en lecture et obtenu un filehandle avant de tenter de l'utiliser et que la variable
$st
sera sensée contenir les données et sera donc initialisée.

Dal
artagon7
Messages postés
273
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
31 août 2019
6 > [Dal]
Messages postés
5251
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 octobre 2019
-
Salut,

En considérant tes remarques, j'ai écrit le programme suivant :

#!/usr/bin/perl 

use strict; 
use warnings; 

my $st; 

open (FICHIER_ENTREE, "fruits.txt"); 
open (FICHIER_ITEM, ">fruit_3.txt");

{
    local $/;
    $st = <FICHIER_ENTREE>;
}

while ($st =~ m/(\\item\s\[\]\s[^\s]+)\s(\\item\s\[\]\s[^\s]+)\s(\\item\s\[\]\s[^\s]+)/sg) 
{
chomp $1; 
chomp $2; 
chomp $3; 
{print FICHIER_ITEM "%-20s%-20s%-20s\n", $1, $2, $3;} 
} 

close FICHIER_ENTREE; 
close FICHIER_ITEM; 

Je vais voir ce que ça va donner.

Merci,
Commenter la réponse de artagon7