IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Optimiser mon extraction de variables


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de theclem35
    Homme Profil pro
    Technicien Réseaux & Télécommunications
    Inscrit en
    Décembre 2007
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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é

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Une idée comme une autre...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    $

  3. #3
    Membre confirmé Avatar de theclem35
    Homme Profil pro
    Technicien Réseaux & Télécommunications
    Inscrit en
    Décembre 2007
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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
    Par défaut
    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!!

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    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.


    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é

  5. #5
    Membre confirmé Avatar de theclem35
    Homme Profil pro
    Technicien Réseaux & Télécommunications
    Inscrit en
    Décembre 2007
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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
    Par défaut
    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

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    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).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Stratégie]optimiser mon application java
    Par Malo dans le forum Langage
    Réponses: 3
    Dernier message: 14/02/2006, 04h45
  2. [C#] Comment optimiser mon constructeur ?
    Par blbird dans le forum C#
    Réponses: 2
    Dernier message: 19/01/2006, 14h41
  3. Visual Basic ne prend pas en compte mon chgt de variable
    Par Crazy_Gun dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 09/12/2005, 14h40
  4. Réponses: 10
    Dernier message: 06/10/2005, 22h25
  5. Optimiser mon code ASP/HTML
    Par ahage4x4 dans le forum ASP
    Réponses: 7
    Dernier message: 30/05/2005, 10h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo