Bonsoir, dans le cadre d'un projet en shell je dois réaliser un fichier bash qui puisse lire ce fichier texte ci dessous :
MoiMoi204 a écrit:
par exemple =somme est une fonction qui devra calculer la somme de 1, 2 et 3
Il ne faut pas utiliser de tableau, je veux donc ranger chaque élément dans une variable avec
Ton script doit lire? Ou interpréter le fichier?
MoiMoi204 a écrit:
mais problème, il m'affiche toujours 1 pour $l2c1 or je voudrais qu'il m'affiche 4
merci beaucoup d'avance pour votre aide :)
Fais:
bash -x tonscript.sh
Et essaye de comprendre ce qu'il fait.
Je n'ai pas compris ce que tu as essayé de faire perso? Pourrais-tu l'expliquer?
Si tu ne dois pas utiliser de tableau, je doute que c'est pour utiliser des variables avec des noms du type <ligne1colonne1>... Il faut probablement interpréter chaque ligne à la volée.
je ne suis pas convaincu de l'utilité de la seconde boucle while.
si tu veux obtenir la somme de 1 et 3, respectivement l1c1 et l1c3, il faut les additionner.
je veux imbriquer deux while parce que je peux n'en faire qu'un mais il me donnera toute la colonne c'est à dire comme pour l'exemple 1 4 =+(l1c1,size(l3c3)) or je les veux séparément
puis j'ai une suite de fonction telles que somme, moyenne, variance etc; je n'aurai qu'à les appeler
KoaTao a écrit:
Bonsoir,
MoiMoi204 a écrit:
Bonsoir, dans le cadre d'un projet en shell je dois réaliser un fichier bash qui puisse lire ce fichier texte ci dessous :
MoiMoi204 a écrit:
par exemple =somme est une fonction qui devra calculer la somme de 1, 2 et 3
Il ne faut pas utiliser de tableau, je veux donc ranger chaque élément dans une variable avec
Ton script doit lire? Ou interpréter le fichier?
Mon script doit pouvoir remplacer dans le fichier texte, =somme(l1c1,l1c3) doit être remplacer par 6 etc pour chaque fonction
MoiMoi204 a écrit:
mais problème, il m'affiche toujours 1 pour $l2c1 or je voudrais qu'il m'affiche 4
merci beaucoup d'avance pour votre aide :)
Fais:
bash -x tonscript.sh
Et essaye de comprendre ce qu'il fait.
Je n'ai pas compris ce que tu as essayé de faire perso? Pourrais-tu l'expliquer?
Si tu ne dois pas utiliser de tableau, je doute que c'est pour utiliser des variables avec des noms du type <ligne1colonne1>... Il faut probablement interpréter chaque ligne à la volée.
- Edité par KoaTao il y a moins de 30s
Le problème est la ligne
l2c1=`echo $lig | cut -d: -f1`
j'aimerais retourner à la ligne pour pouvoir mettre 4 dans la variable l2c1 mais il recommence à la 1ère ligne
pour mieux comprendre mon fichier texte qui est donné comme ceci
Tes deux boucles Tant que lisent la même entrée (stdin) je suppose:
while read ligne1; do
while read lignesRestantesDuFichier; do
echo "Deuxième boucle: $lignesRestantesDuFichier"
done
echo "Fin du fichier"
done < fichier.txt
Ensuite, sur comment implémenter tous ça pour tout interpréter sans utiliser de tableau... c'est différent. Est-ce que le fichier d'input peut changer? Nb de lignes? Colonnes? C'est très confus pour moi.
Tes deux boucles Tant que lisent la même entrée (stdin) je suppose:
while read ligne1; do
while read lignesRestantesDuFichier; do
echo "Deuxième boucle: $lignesRestantesDuFichier"
done
echo "Fin du fichier"
done < fichier.txt
Ensuite, sur comment implémenter tous ça pour tout interpréter sans utiliser de tableau... c'est différent. Est-ce que le fichier d'input peut changer? Nb de lignes? Colonnes? C'est très confus pour moi.
Ça nous explique pas ce que tu veux faire mais bon...
De ce que je comprend, chaque ligne peut faire appel à des valeurs se trouvant sur les lignes précédentes. Donc il faut d'abord interpréter la ligne 1 et stocker le résultat pour pouvoir y accéder ci besoin, puis la ligne 2 et ainsi de suite.
Un chose toute simple qu'on peut faire est:
while read ligne; do
####
# Faire l'interprétation ici
####
retour+="$resultatInterprétation\n"
done <data.txt
echo -e "$retour"
Il existe fort probablement de meilleures solutions.
Ça nous explique pas ce que tu veux faire mais bon...
De ce que je comprend, chaque ligne peut faire appel à des valeurs se trouvant sur les lignes précédentes. Donc il faut d'abord interpréter la ligne 1 et stocker le résultat pour pouvoir y accéder ci besoin, puis la ligne 2 et ainsi de suite.
Un chose toute simple qu'on peut faire est:
while read ligne; do
####
# Faire l'interprétation ici
####
retour+="$resultatInterprétation\n"
done <data.txt
echo -e "$retour"
Il existe fort probablement de meilleures solutions.
- Edité par KoaTao il y a 12 minutes
Il faut en effet procéder ligne par ligne comme vous le dites mais je ne sais pas comment faire
j'essaye cette commande basique mais il parcourt encore tout le fichier et non la première ligne uniquement
while read ligne
do
retour+=$ligne
done <data.txt
echo -e "$retour"
Si tu ne comprends pas ce que tu as écrit dans ton premier script (la structure while read line; do #ACTION; done < fichier.input), tu ne pourras pas résoudre cet exercice.
Qui ressemble fortement à un tableau (probablement la raison pour laquelle l'utilisation de tableau est prohibé).
On peut donc identifier chaque champs de chaque ligne. Avec la boucle, on peut aussi lire 4 champs par 4 champs.
Si on reste dans un truc tout simple:
on interprète chaque ligne et on place le résultat dans une seule variable qui stockera tous les résultats dans une chaîne de caractère avec un séparateur de champ défini;
Ensuite, lors de l'interprétation, lorsqu'on aura besoin de récupérer la valeur d'un champ d'une ligne précédente, il suffira d'extraire le champ (qu'on sait calculer) correspondant dans notre variable.
while read lig
do
l1c1=`echo $lig | cut -d: -f1`
l1c2=`echo $lig | cut -d: -f2`
l1c3=`echo $lig | cut -d: -f3`
l1c4=`echo $lig | cut -d: -f4`
if [ ${l1c4:0:1} = '=' ]; then
if [[ $l1c4 =~ "somme" ]]; then
if [[ $l1c4 =~ "l1c1" ]] && [[ $l1c4 =~ "l1c3" ]]; then
somme $l1c1 $l1c2 $l1c3
fi
elif [[ $l1c4 =~ "moyenne" ]]; then
if [[ $l1c4 =~ "l1c1" ]] && [[ $l1c4 =~ "l1c3" ]]; then
moyenne $l1c1 $l1c2 $l1c3
fi
else
echo ko
fi
fi
echo "$l1c1:$l1c2:$l1c3:$l1c4"
done <data.txt
comme vous le dites ça fonctionnera pour la première ligne mais si j'essaye avec la deuxième ligne je ne peux plus récupérer les premières valeurs de la première ligne c'est à dire 1 2 et 3
« Allez! avec une tenaille, et en vous servant uniquement de votre main faible (la gauche pour les droitiers...), faites une miniature de la Joconde. »
#!/bin/bash
nl=0
while read l$((++nl))
do
lnl=l$nl
nc=0
while read -d :
do
r=l${nl}c$((++nc))
echo ${!r}
done <<<${!lnl}:
echo
done < ./tonFichier
les points d'exclamation introduisent une indirection, c'est-à-dire une référence à un nom de variable :
$ var=foobar
$ nom=var
$ echo ${!nom}
foobar
dans le code précédent, qui lit tonFichier, les noms de variables sont construits en fonction du numéro de ligne (l${nl}) et du numéro de champ (c${nc})
bon courage.
- Edité par dantonq 3 décembre 2019 à 4:23:08
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
somme(){
sum=0
for item in $@;
do
sum=$(($sum + $item))
done
echo $sum
}
et voici mon code
nl=0
while IFS=: read l$((++nl))
do
lnl=l$nl
#echo "ligne $nl = ${!lnl}"
nc=0
while read -d : ${lnl}c$((++nc))
do
r=${lnl}c$nc
if [[ "$r = ${!r}" =~ "somme" ]]
then
if [[ "$r = ${!r}" =~ "l1c1" ]] && [[ "$r = ${!r}" =~ "l1c3" ]]
then
somme ${lnl}c$1 ${lnl}c$2 ${lnl}c$3
fi
fi
#echo "$r = ${!r}"
done <<<${!lnl}:
echo
done < data.txt
l'erreur se trouve à ligne
somme ${lnl}c$1 ${lnl}c$2 ${lnl}c$3
j'aimerais en effet calculer la somme du premier nombre de la première ligne ,du deuxième nombre de la première ligne et du troisième de la première ligne ( càd 1,2 et 3 )
je pensais que tu voulais exécuter l'instruit somme(l1c1,l1c3)
que je lis comme la somme du premier et du troisième champs de la première ligne.
comme l'a suggérer KoaTao :
Il faut probablement interpréter chaque ligne à la volée.
donc réutiliser les données du fichiers, et procéder à un autre découpage si un champ contient le nom d'une fonction pour récupérer le nom de la fonction et les données auxquelles elle s'applique.
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
oui la fonction addition permet d'additionner deux champs, la fonction somme permet de sommer une suite de champs de la même ligne débutant par le champ argument1 et finissant par le champ argument2
ça veut dire que le code que vous m'avez fourni n'est plus adéquat au sujet ?
c'est un début, pour te montrer comment construire des variables, et les retrouver.
il reste à faire interpréter les données fournies dans le fichiers.
ça ne doit pas être très différent : le fichier donne des références de nom de variables, il faut faire en sorte (avec une indirection aussi ?) qu'elles affichent les valeurs correctes.
si tu n'y arrives pas, je ferai des tests demain.
-- bonne nuit, à demain.
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
Tu devrais créer une fonction pour parser qui retourne la chaîne de caractère que doit contenir le champs interpréter. Je te conseille de découper au maximum ton programme en tâche simple à réaliser, plutôt que d'essayer de tout faire d'un coup.
Tu devrais quand même éviter au maximum d'avoir des structures if-then-elif imbriquées, car ça va tuer la lisibilité.
#!/usr/bin/env bash
parsePermierCara(){
field="$1"
case "${field:0:1}" in
"=")
echo "Affectation"
#Continuer à parser
;;
*)
#Rien à faire dans les autres cas
echo "$field"
;;
esac
}
nl=0
while IFS=: read l$((++nl))
do
lnl=l$nl
nc=0
while read -d : ${lnl}c$((++nc))
do
r=${lnl}c$nc
declare "${r}"=$(parsePermierCara "${!r}")
echo "${!r}"
done <<<${!lnl}:
done < fichier.txt
Le script n'est bien sur pas complet, mais l'idée est d'interpréter chaque champs en cherchant les caractères ayant une signification spéciale (comme «=», «[» «(» «)» par exemple), et d'afficher le résultat. Ensuite, on assigne ce résultat à la variable correspondant au champ.
Une fois que tu as réalisé ton «interpréteur», il ne te reste plus qu'à formater la sortie.
J'utilise
declare "${r}"=$(parsePermierCara "${!r}")
Pour assigner une nouvelle valeur au champ interprété.
lecture fichier txt avec bash
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique