Précédent   Forum des professionnels en informatique > Systèmes > Autres systèmes > Unix
Unix Forum d'entraide sur les systèmes Unix et dérivés (*BSD, AIX, etc.). Avant de poster ->F.A.Q BSD F.A.Q. Aix
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 08/02/2012, 20h58   #1
Membre du Club
 
Avatar de theclem35
 
Homme Clément
Technicien Réseaux & Télécommunications
Inscription : décembre 2007
Messages : 148
Détails du profil
Informations personnelles :
Nom : Homme Clément
Localisation : France, Vendée (Pays de la Loire)

Informations professionnelles :
Activité : Technicien Réseaux & Télécommunications
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : décembre 2007
Messages : 148
Points : 49
Points : 49
Par défaut Optimiser mon extraction de variables

Salut à tous,

J'ai un script bash grace auquel je lis un fichier.
Dans ce fichier, il y a plusieurs lignes qui contiennent des champs et des valeurs comme suit :
Code :
1
2
couleur=rouge; objet=maison; nom=plop; prenom=pasplop; adresse=0xFF2245; date=today
couleur=bleu; objet=bateau; nom=gloup; prenom=pasgloup; adresse=0xFF2250; date=hier
Je souhaite remettre en forme ces valeurs de la forme suivante :
Code :
1
2
3
4
5
6
ligne_de_valeurs	couleur	rouge
ligne_de_valeurs	objet	maison
ligne_de_valeurs	nom	plop
ligne_de_valeurs	prenom	pasplop
ligne_de_valeurs	adresse	0xFF2245
ligne_de_valeurs	date	today
Dans un fichier portant le nom+".txt", puis idem pour chaque ligne du fichier de base.

J'ai créé un script qui fonctionne très bien, mais je pense qu'il peut etre GRANDEMENT optimisé. En effet je pense que je me suis galéré un peu, mais mes faibles connaissances dans la programmation unix, ne m'ont pas laissé le choix.
Voici mon script tel qu'il est à l'heure actuelle :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash

fichier=/home/Moi/Desktop/myfile.txt
rep_dest=dest/
rep_courant=$(pwd)

while read ligne
do
	i=1
	echo > $rep_dest"fichier_temp"
	while [ "$(echo $ligne | cut -d";" -f$i)" ]
	do
		champ=$(echo $ligne | cut -d" " -f$i | cut -d"=" -f1) #On copie le champ
		valeur=$(echo $ligne | cut -d" " -f$i | cut -d"=" -f2 | cut -d";" -f1) #On copie la valeur associé au champ
		if [ "$champ" = "nom" ]
		then
			nom_fichier="$valeur.txt"
		fi
		echo -e "ligne_de_valeurs\t$champ\t$valeur" >> $rep_dest"fichier_temp"
	((i++))
	done
	if [ ! -f "$rep_dest$nom_fichier" ]
	then
		echo -e "Arrivée d'un nouveau nom > $rep_courant/$rep_dest$nom_fichier"
	fi
done < $fichier
Je pense que ce code va faire bondir certains Si vous pouviez m'aider dans son optimisation, je vous en saurait gré
theclem35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2012, 11h04   #2
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Salut,

Une idée comme une autre...

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
$ ls
fich.txt  foo.sh*

$ cat fich.txt 
couleur=rouge; objet=maison; nom=plop; prenom=pasplop; adresse=0xFF2245; date=today
couleur=bleu; objet=bateau; nom=gloup; prenom=pasgloup; adresse=0xFF2250; date=hier

$ cat foo.sh 
#! /bin/bash

#set -xv

while read line
do
nom=$(egrep -o '\bnom=[^;]*' <<<${line})
sed -n 's/=/\t/g;s/; /\n/g;s/^/Ligne de valeurs\t/Mg;w '"${nom#*=}"'.txt' <<<${line}
done < fich.txt

$ ./foo.sh 

$ ls
fich.txt  foo.sh*  gloup.txt  plop.txt

$ cat plop.txt 
Ligne de valeurs	couleur	rouge
Ligne de valeurs	objet	maison
Ligne de valeurs	nom	plop
Ligne de valeurs	prenom	pasplop
Ligne de valeurs	adresse	0xFF2245
Ligne de valeurs	date	today

$ cat gloup.txt 
Ligne de valeurs	couleur	bleu
Ligne de valeurs	objet	bateau
Ligne de valeurs	nom	gloup
Ligne de valeurs	prenom	pasgloup
Ligne de valeurs	adresse	0xFF2250
Ligne de valeurs	date	hier

$
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 09/02/2012, 17h52   #3
Membre du Club
 
Avatar de theclem35
 
Homme Clément
Technicien Réseaux & Télécommunications
Inscription : décembre 2007
Messages : 148
Détails du profil
Informations personnelles :
Nom : Homme Clément
Localisation : France, Vendée (Pays de la Loire)

Informations professionnelles :
Activité : Technicien Réseaux & Télécommunications
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : décembre 2007
Messages : 148
Points : 49
Points : 49
Trop easy quoi ...

Enfin ce que je remarque c'est que t'as pas trouvé mieux pour tester si mon fichier existait déjà, et dans le cas contraire m'avertir de la création d'un nouveau
Ca veux dire que j'étais pas mauvais de ce coté la

Pour le reste ... C'est possible de me donner quelques explications ?

Merci!!
theclem35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2012, 18h27   #4
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
nom=$(egrep -o '\bnom=[^;]*' <<<${line})
On récupère "nom=blabla".
\b
Correspond à une chaîne vide à l'extrémité d'un mot. Limite entre un mot et un caractère autre qu'un mot, en gros on évite de récupérer aussi "prenom=xxx".
[^;]*
On récupère tout (*), jusqu'à ce qu'on rencontre un ";". le "[^;]" représente la négation.

<<<${line}
Redirection en entrée. On injecte la ligne.




sed -n
On n'affiche rien sur la sortie standard.

s/=/\t/g
On substitue tous (g) les signes "égale" par une tabulation (\t)

s/; /\n/g
On substitue tous les ";" suivis d'un espace par des fins de ligne (\n)

s/^/Ligne de valeurs\t/Mg
On substitue tous les débuts (^) de ligne par "Ligne de valeurs" suivi d'une tabulation "\t".
Le flag "M" est un peu spécial. En fait un flux de données dans la mémoire principale de sed est vu comme une seule et même ligne, même si cette ligne contient des caractères fin de ligne. Donc sans le flag "M", la commande ajouterait juste le motif au début de la ligne et c'est tout. Grâce au flag "M", sed reconsidère chaque caractère \n comme étant la fin d'une ligne et le début d'une autre. Ce qui permet de rajouter le motif devant chaque ligne.

w '"${nom#*=}"'.txt'
La commande "w" (write) permet quant à elle d'écrire dans le fichier qui la suit.
${nom#*=}
Ça c'est c'est propre au "bash". On supprime tout ce qui se trouve avant le signe égale et le signe lui même, donc il ne reste que le nom.


Citation:
Enfin ce que je remarque c'est que t'as pas trouvé mieux pour tester si mon fichier existait déjà, et dans le cas contraire m'avertir de la création d'un nouveau
Il te suffit de rajouter un test après le "grep" et avant le "sed" et le tour est joué
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2012, 18h57   #5
Membre du Club
 
Avatar de theclem35
 
Homme Clément
Technicien Réseaux & Télécommunications
Inscription : décembre 2007
Messages : 148
Détails du profil
Informations personnelles :
Nom : Homme Clément
Localisation : France, Vendée (Pays de la Loire)

Informations professionnelles :
Activité : Technicien Réseaux & Télécommunications
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : décembre 2007
Messages : 148
Points : 49
Points : 49
J'ai tout compris ! Vraiment impressionant, c'est quand même bien avancé.
Je ne connaissais pas la négation avec le ^ mais juste le début de ligne.

Merci beaucoup
theclem35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2012, 19h10   #6
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Citation:
Je ne connaissais pas la négation avec le ^ mais juste le début de ligne.
Uniquement lorsqu'il est entre crochets [^;]*.

Si on écrit ".*" on récupère tout.
Avec "[^;]*", on récupère tout jusqu'à ce qu'on rencontre un ";" (qu'on ne prend pas ça va de soi).
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h53.


 
 
 
 
Partenaires

Hébergement Web