Remplacer dans un fichier les nombres par leur couleur

Fermé
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 - 20 déc. 2022 à 12:45
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 - 3 janv. 2023 à 15:48

Bonjour,on m'a donné un exercice j'ai presque la solution sauf que il y a des trucs qui font que ma solution ne marche pas totalement

EXo

on nous donne un fichier contenant des nombres(soit z ce nombre)suivi de %

Si z appartient a [0;38[ on colore ce nombre dans le fichier texte en vert

Si z est dans [38;54[ on colore en bleu

etc 

Supposons que dans mon fichier j'ai

Jaune 22% représente ...
43% de chocolat

Ca doit colorer 22% en vert et 43% en bleu dans le fichier texte 

J'ai écris d'abord une fonction auxiliaire qui prend en argument un nombre et le colore en suivant les indications d'intervalle donné par l'énoncé

couleur(){
    nombre=$1
    
    if [[ $nombre -ge 0 && $nombre -lt 38 ]]
    then
        
        echo -e "\e[48;5;2m${nombre_entier_to_char}\e[0m"
   
    elif [[ $nombre -ge 38 && $nombre -lt 54 ]]
    then
       
        echo -e "\e[48;5;6m${nombre_entier_to_char}\e[0m"
    fi
}

Ensuite dans mon code prinipal je mets

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}
                    
                    couleur $nombre
                    #sed -i s/$nombre_entier_to_char/$c/g fichier
                fi
            done
        fi
    done 
    
done < fichier

Rien ne s'affiche du coup j'ai mit set -x

ça récupére bien dans nombre le nombre sans son % mais ça marche pas

Bon normalement pour appliquer ces changement dans le fichier c'est sed -i ...mais bon ca fait des trucs bizarre du coup je l'ai mit en commentaire

PPouvez m'aider svp a resoudre mon probleme.Peut etre je m'y prend pas
 

A voir également:

3 réponses

mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 7 748
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]
    • 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

Bonne chance

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
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.

0
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 7 748
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

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
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

0
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 7 748
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

0