#1 Le 26/10/2020, à 12:37
- Smwa
[RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
Bonjour à toutes et tous,
je reviens vers vous car dans l'élaboration de mon projet je bloque sur un petit quelque chose.
Je souhaite à partir d'un fichier texte, recopier des lignes dans un nouveau fichier par catégorie.
Un exemple sera sans doute plus parlant
exemple simplifié:
fic_ini (au format categorie:groupe)
eleve:eleve
prof:prof
stagiaire:stagiaire
liste_personne (au format prenom:categorie)
lulu:eleve
toto:prof
poum:stagaire
bob:client
gege:fournisseur
mon script de tri:
while read ligne
do
cat_personne=`echo $ligne | cut -d ':' -f2`
while read line
do
filtre=`echo $line | cut -d ':' -f1` #récupère la catégorie qui servira au tri
groupe=`echo $line | cut -d ':' -f2` #récupère le groupe pour créer un nouveau fichier du même nom
case "$cat_personne" in
$filtre) echo $ligne >> $groupe ;;
*) echo $ligne >> autre ;;
esac
done < fic_ini
done < liste_personne
ma solution ne fonctionne qu'en partie.
Dans le code que j'ai fait, je me retrouve avec un fichier "autre" contenant toutes les lignes en autant d'exemplaire qu'il y a de ligne dans mon fic_ini
J'aimerai réussir à gérer, le cas "autre", et pour les personnes avec une catégorie non référencée dans mon fic_ini, copier leurs infos dans un fichier "autre"
Auriez-vous des pistes s'il vous plait ?
Je vous remercie d'avoir pris le temps de me lire.
Bonne journée !!
Dernière modification par Smwa (Le 26/10/2020, à 17:27)
Hors ligne
#2 Le 26/10/2020, à 13:08
- Watael
Re : [RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
salut,
du fait de la simplification peut-être, je ne vois pas l'intérêt du premier fichier (fic_ini)...
sinon, ça pourrait être un travail pour join.
Dernière modification par Watael (Le 26/10/2020, à 13:09)
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#3 Le 26/10/2020, à 13:47
- Smwa
Re : [RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
bonjour et merci pour ta réponse.
Oui je l'ai ultra simplifié pour pouvoir expliquer clairement ce que je veux faire et moi même comprendre ce que je pourrai modifier sur cet exemple simple, pour l'adapter ensuite à mon projet qui a une dimension bien plus complexe.
Mon fic_init pour le projet contient beaucoup de champs et de lignes, quand au fichier liste_personne. J'ai tronqué pour plus de clarté.
Je ne peux pas rajouter de catégories client:autre ou fournisseur:autre dans mon fichier init, enfin si, je peux mais ça ne résoudra pas mon souci, car lors des test le prof rajoutera justement des catégories variées dans la liste_personne, qui ne seront pas dans fic_init, et ces catégories doivent partir vers "autre". Je dois donc trouver un moyen de généraliser le cas des catégories "autres".
Concernant le join dans le manuel je vois "join - Fusionner les lignes de deux fichiers ayant des champs communs", et même en regardant les options, je ne comprends pas comment je peux l'utiliser dans mon cas en fait. J'ignore si je dois rajouter une ligne dans mon fic_init sous la forme ???:autre, ou si je doit intervenir dans la partie *) de mon case.
(je suis vraiment très novice, mais j'apprends)
D'après mon exemple, le résultat que je souhaite serait, une copie des lignes de liste_personne par catégorie.
Toujours d'après mon exemple je voudrai obtenir :
un fichier "eleve"
lulu:eleve
un fichier "prof
toto:prof
un fichier "stagiaire"
poum:stagiaire
un fichier "autre" qui récupère tout ce qui n'est ni élève, ni stagiaire ni prof.
bob:client
gege:fournisseur
Dernière modification par Smwa (Le 26/10/2020, à 14:10)
Hors ligne
#4 Le 26/10/2020, à 14:10
- pingouinux
Re : [RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
Bonjour,
Voici une suggestion :
>eleve
>prof
>autre
while IFS=: read categ cat_personne
do
line=$(grep "^$cat_personne:" fic_ini)
if [ "$line" ]
then
groupe=$(cut -d: -f2 <<<"$line")
else
groupe=autre
fi
echo "$categ:$cat_personne" >> "$groupe"
done < liste_personne
Dans fic_ini et dans liste_personne un des "stagiaire" est mal orthographié.
Hors ligne
#5 Le 26/10/2020, à 14:11
- Watael
Re : [RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
$ join -e 'INCONNU' -a 2 -t ':' -j 2 -o 2.1 1.2 <(sort -t':' -k2,2 /tmp/fic_ini) <(sort -t ':' -k 2 /tmp/liste_personne)
bob:INCONNU
lulu:eleve
gege:INCONNU
toto:prof
poum:stagaire
ça devrait simplifier la lecture pour un traitement ultérieur.
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#6 Le 26/10/2020, à 14:21
- Smwa
Re : [RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
Bonjour,
oui j'ai corrigé stagiaire, merci !!
merci beaucoup, je ne connaissais pas la syntaxe while IFS=: read
Je vais essayer de la comprendre et de l'exploiter, car elle semble résoudre mon problème sur cet exemple
Hors ligne
#7 Le 26/10/2020, à 14:25
- pingouinux
Re : [RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
Même principe, mais plus simple.
>eleve
>prof
>autre
while IFS=: read categ cat_personne
do
line=$(grep "^$cat_personne:" fic_ini) && groupe=$(cut -d: -f2 <<<"$line") || groupe=autre
echo "$categ:$cat_personne" >> "$groupe"
done < liste_personne
Hors ligne
#8 Le 26/10/2020, à 16:43
- Smwa
Re : [RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
Rebonjour,
j'ai décortiqué la syntaxe while IFS= read pour bien comprendre et je l'ai appliqué à un autre exemple.
ça ne marche qu'en partie et j'ai du mal à comprendre pourquoi. Je pensais avoir bien saisi comment manipuler cette boucle, mais visiblement non. Ou alors je loupe un détail peut-être ?
Je ne comprends pas pourquoi mon fichier .txt se retrouve dans autre et n'a pas suivi le tri comme mon toto.mp4 et mon lulu.pdf par exemple qui eux sont bien arrivés où il faut.
Idem pour mon berceuse.mp3 envoyé dans autre
et soleil.jpg aussi.
Quelque chose m'a échappé mais je n'arrive pas à voir quoi
Pourriez-vous encore m'aiguiller sur ce que je ne semble pas saisir s'il vous plait ?
Dernière modification par Smwa (Le 26/10/2020, à 17:24)
Hors ligne
#9 Le 26/10/2020, à 17:00
- LeoMajor
Re : [RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
bonjour
:~$ cat ~/tmps/liste_personnes
lulu:eleve
toto:prof
riri:stagiaire
bob:client
gege:fournisseur
lolo:eleve
lala:eleve
tata:prof
titi:prof
fifi:stagiaire
lili:eleve
:~$ awk -F: '/eleve|prof|stagiaire/ {n[$2]++; c[$2".name."n[$2]]=$1; c[$2".count"]=n[$2] }; !/eleve|prof|stagiaire/ {n["autres"]++; c["autres.name."n["autres"]]=$1":"$2; c["autres.count"]=n["autres"] }; END { for (ci in c)print ci,"=",c[ci] } ' ~/tmps/liste_personnes | sort
autres.count = 2
autres.name.1 = bob:client
autres.name.2 = gege:fournisseur
eleve.count = 4
eleve.name.1 = lulu
eleve.name.2 = lolo
eleve.name.3 = lala
eleve.name.4 = lili
prof.count = 3
prof.name.1 = toto
prof.name.2 = tata
prof.name.3 = titi
stagiaire.count = 2
stagiaire.name.1 = riri
stagiaire.name.2 = fifi
je ne vois pas l'intérêt de créer des fichiers temporaires
en bash, cela va être pareil, à part que tu vas utiliser declare -A c ( tableau associatif) ...
Hors ligne
#10 Le 26/10/2020, à 17:13
- Watael
Re : [RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
Quelque chose m'a échappé mais je n'arrive pas à voir quoi
le script cherche plain, pas txt.
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#11 Le 26/10/2020, à 17:16
- pingouinux
Re : [RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
Je ne comprends pas pourquoi mon fichier .txt se retrouve dans autre et n'a pas suivi le tri comme mon toto.mp4 et mon lulu.pdf par exemple qui eux sont bien arrivés où il faut.
Idem pour mon berceuse.mp3 envoyé dans autre
et soleil.jpg aussi.
Par exemple, pour momo.txt, le type est plain, mais tu cherches ce mot plain en début de ligne du fichier fic_init, et il n'y est pas.
Hors ligne
#12 Le 26/10/2020, à 17:20
- Smwa
Re : [RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
Smwa #8 a écrit :Je ne comprends pas pourquoi mon fichier .txt se retrouve dans autre et n'a pas suivi le tri comme mon toto.mp4 et mon lulu.pdf par exemple qui eux sont bien arrivés où il faut.
Idem pour mon berceuse.mp3 envoyé dans autre
et soleil.jpg aussi.Par exemple, pour momo.txt, le type est plain, mais tu cherches ce mot plain en début de ligne du fichier fic_init, et il n'y est pas.
Haaa, merci !!
donc c'est à cause du ^ avant $type dans la ligne si je comprend bien
Je maîtrise très mal les expression régulières !!
Dernière modification par Smwa (Le 28/10/2020, à 17:21)
Hors ligne
#13 Le 26/10/2020, à 17:26
- Smwa
Re : [RESOLU] Bash - gérer un case en fonction de la lecture d'un fichier
Merci beaucoup pour votre aide !! ça fonctionne parfaitement et en prime j'ai appris et compris une nouvelle commande !!! <3
Je passe le sujet en résolu
Bonne fin de journée à tous !
Dernière modification par Smwa (Le 28/10/2020, à 17:21)
Hors ligne