Remplacer dans un fichier les nombres par leur couleur
Fermémamiemando Messages postés 33582 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 mars 2025 - 3 janv. 2023 à 15:48
- Remplacer dans un fichier les nombres par leur couleur
- Fichier rar - Guide
- Comment réduire la taille d'un fichier - Guide
- Comment ouvrir un fichier epub ? - Guide
- Remplacer disque dur par ssd - Guide
- Ouvrir un fichier .bin - Guide
3 réponses
20 déc. 2022 à 16:54
Bonjour,
Pour déboguer ton script, il faut regarder avec des echo et set -x quelles section de code sont traversées. Tu verras que ton script n'entre jamais dans le "if" ligne 17 car tu as utilisé $caractere au lieu de $c.
Ensuite il serait plus logique que ta fonction couleur retourne une valeur, que tu en récupères le résultat comme expliqué ici, et qu'ensuite seulement tu construises la chaîne corrigée.
Enfin, si tu fais un sed -i s/.../.../g alors toutes les occurrences de pourcentages seront modifiées de la même valeur. Malheureusement, rien ne dit que tous les pourcentages figurant dans une même ligne soient tous dans la même plage de valeur. Le code est donc faux dans le cas général. Il faut que tu itères dans une ligne sur chaque occurrence de pourcentage et que tu fasses leur substitution indépendamment.
Il y a un autre problème, si ton fichier contient par exemple "48 toto %" , alors toute cette chaîne sera colorée avec ton algorithme alors que j'imagine qu'il ne faut pas.
Bref, ce que je ferais c'est quelque chose dans ce genre :
- flag = false (cette variable indique si on semble être en train de lire un pourcentage).
- Pour chaque caractère c de la ligne l à l'index i
- Si flag = False
- Si c est un entier
- (on est peut être en train de découvrir un pourcentage)
- debut = i
- flag = True
- Sinon
- Écrire l[i]
- Si c est un entier
- Sinon
- Si c n'est pas un chiffre
- n = l[debut:i]
- Si c est % (alors on a un pourcentage bien formé, c'est-à-dire collé à droite d'un entier)
- Déterminer les balises debut_couleur et fin_couleur en fonction de n
- Écrire debut_couleur n % fin_couleur
- Sinon (alors on est juste tombé sur un nombre entier qu'on réécrit tel quel)
- Écrire n
- (on réinitialise les variables pour détecter un nouveau pourcentage)
- flag = False
- debut = i
- Si c n'est pas un chiffre
- Si flag = False
Bonne chance
Modifié le 27 déc. 2022 à 16:51
Merci mamiemando
J'ai presque résolu mon soucis
Et je me suis trompé, j'avais mal compris l'énoncé : en fait eux ils veulent genre que j'obtienne l'affichage :
Il faut que toute la ligne "Jaune 22% représente ..." soit coloréz en vert et pas seulement le nombre (ça j'ai réussi à le faire)
Du coup, ma fonction couleur j'ai ajouté un second argument qui est ligne=$2 et j'ai remplacé ${nombre_entier_to_char} par $ligne mais aussi dans le code principal j'ai modifié :
couleur $nombre
par :
couleur $nombre $ligne
... sauf que il y a un soucis.
Lorsque j'ai une ligne qui est :
ligne=' papa a mangé du chocolat'
Au lieu de remplacer toute la ligne par sa valeur, ça prend en compte que le premier mot de la ligne à savoir "papa" et non le reste de la ligne
Comment ça se fait? ou bien sed n'est pas adapté si la chaîne de caractère est trop longue ?
J'ai juste ça qui me bloque.
27 déc. 2022 à 16:57
Tu n'as pas besoin de sed c'est se compliquer la vie pour rien. Tu as juste besoin d'écrire :
echo $begin_color$ligne$end_color
où :
- begin_couleur contient la séquence d'échappement pour écrire dans la bonne couleur, par exemple :
begin_color="\[\033[01;33m\]"
-
end_couleur contient la séquence d'échappement pour retourner dans le style par défaut :
end_color="\[\033[00m\]"
Si tu veux plus de précisions, il faudrait plutôt partager le code modifié (qui ne doit pas être bien long).
Bonne chance
Modifié le 27 déc. 2022 à 17:50
couleur(){ nombre=$1 ligne=$2 if [[ $nombre -ge 0 && $nombre -lt 38 ]] then echo -e "\e[48;5;2m$ligne\e[0m" elif [[ $nombre -ge 38 && $nombre -lt 54 ]] then echo -e "\e[48;5;6m$$ligne\e[0m" fi }
while read ligne do l=${#ligne} for ((i=0;i<l;i++)) do c=${l:i:1} if [[ $c =~ [0-9] ]] then # début du nombre debut=$i for ((j=i;j<l;j++)) do c=${ligne:j:1} if [[ $caractere == "%" ]] then fin=$((j-1)) nombre=${ligne:debut:fin-debut+1} c=$(couleur $nombre $ligne) fi done i=$((fin+1)) fi done done < fichier
en fait le sed je l'utilse car je veux modifier aussi le fichier(d'ou l'option -i) pourque lorsque je fait cat fichier ,ça m'affiche le fichier avec les lignes colorés
3 janv. 2023 à 15:48
Il y a encore des confusions dans les noms de variables. En l'état, ligne 17, caractere devrait être remplacé c. De manière générale, tu devrais éviter d'appeler toutes tes variables c et leur choisir des noms distincts et parlants.
Concernant l'énoncé de ton exercice, si toute la ligne doit être colorée, il faut juste une fois la couleur déterminée écrire :
Il te faut quand même extraire le pourcentage pour déterminer couleur. Le plus simple serait de l'extraire avec egrep en faisant l'hypothèse qu'il n'y a qu'un pourcentage par ligne (sinon on ne sait pas quelle couleur utiliser).
pourcentage=$(echo "$ligne" | egrep -o "[0-9]{1,3}%" | cut -d "%" -f1)
Du coup, même plus besoin de t'embêter à calculer debut et fin. De là tu déduis l'éventuelle couleur et s'il y en a une tu écris :
echo "$debut_couleur$ligne$fin_couleur"
... et sinon :
echo "$ligne"
Je te déconseille de faire un sed, surtout dans un fichier que tu es en train de lire. Cela peut engendrer des effets de bords, en particulier sur les lignes que tu n'as pas fini de lire. Il vaut mieux simplement écrire le résultat sur la sortie standard, quitte à rediriger le résultat vers un fichier résultat au moment d'appeler le script.
Bonne chance