Alignement des mots

Résolu/Fermé
artagon7 Messages postés 415 Date d'inscription dimanche 6 novembre 2005 Statut Membre Dernière intervention 11 février 2024 - 13 juin 2019 à 18:55
artagon7 Messages postés 415 Date d'inscription dimanche 6 novembre 2005 Statut Membre Dernière intervention 11 février 2024 - 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

3 réponses

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 14 juin 2019 à 09:41
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
1
artagon7 Messages postés 415 Date d'inscription dimanche 6 novembre 2005 Statut Membre Dernière intervention 11 février 2024 7
14 juin 2019 à 19:11
Salut Dal,

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

Merci beaucoup.
0
artagon7 Messages postés 415 Date d'inscription dimanche 6 novembre 2005 Statut Membre Dernière intervention 11 février 2024 7
18 juin 2019 à 17:20
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
1
artagon7 Messages postés 415 Date d'inscription dimanche 6 novembre 2005 Statut Membre Dernière intervention 11 février 2024 7
15 juin 2019 à 23:21
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,
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 17 juin 2019 à 09:48
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
0
artagon7 Messages postés 415 Date d'inscription dimanche 6 novembre 2005 Statut Membre Dernière intervention 11 février 2024 7 > [Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024
17 juin 2019 à 21:25
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,
0