Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#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 sad
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

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.

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

pingouinux a écrit :
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 ! smile

Dernière modification par Smwa (Le 28/10/2020, à 17:21)

Hors ligne