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

Linux Discussion :

[Shell] Enrichissement de fichier


Sujet :

Linux

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 26
    Par défaut [Shell] Enrichissement de fichier
    Bonjour,

    Je bute sur un problème qui me semblait fort simple et qui pour moi ne l'est pas fianlement

    J'ai donc 2 fichiers :
    A et B

    A est composé de x Lignes de 2 champs de 11 carctères separes par une virgule
    B est un fichier quelconque

    Je voudrais rechercher dans B le premier champ de A, et si je le trouve ajouter à la fin de la ligne correspondante dans B le second champ de A, ceci jusqu'à la fin du parcours de B.

    Pourriez vous m'aider svp ?
    Merci d'avance.

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 851
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par MarcCC Voir le message
    Bonjour,

    Je bute sur un problème qui me semblait fort simple et qui pour moi ne l'est pas fianlement

    J'ai donc 2 fichiers :
    A et B

    A est composé de x Lignes de 2 champs de 11 carctères separes par une virgule
    B est un fichier quelconque

    Je voudrais rechercher dans B le premier champ de A, et si je le trouve ajouter à la fin de la ligne correspondante dans B le second champ de A, ceci jusqu'à la fin du parcours de B.

    Pourriez vous m'aider svp ?
    Merci d'avance.
    Pas de problème. Un parcours de B où, pour chaque ligne, on va voir si l'info de "A" y est. Si la ligne contient l'info on y rajoute le champ de A. Et on écrit le tout dans C parce qu'on ne peut pas facilement à la fois lire et écrire
    Un peu long car tu feras A x B itérations mais simple à écrire en shell (mais moi je conseillerais le Python)
    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
    #!/bin/bash
    # Création d'un flux contenant le fichier à lire et d'un flux redirigé fers le fichier à écrire
    exec 3<fichierB
    exec 5>fichierC
     
    # Lecture de B
    while read ligneB 0<&3
    do
        # Petit affichage de contrôle (facultatif mais ça montrera la progression)
        echo "$ligneB"
     
        # Création d'un flux contenant le fichier à lire
        exec 4<fichierA
        # Lecture de A
        while read ligneA 0<&4
        do
            # Extraction champ 1 de la ligne A
            c1=`echo $ligneA |cut -f1 -d,`
     
            # Si le champ 1 est dans la ligne B
            if echo $ligneB |grep "$c1" 1>/dev/null
            then
                 # On y rajoute le champ 2 de la ligne A
                 ligneB="$ligneB `echo $ligneA |cut -f2 -d,`"
            fi
        done
     
        # On écrit la ligne finale dans C
        echo "$ligneB" 1>&5
    done
    Si les deux fichiers ne sont pas trop gros ça devrait aller. Sinon faut l'écrire en Python (1000 fois plus rapide). Je le ferais bien ici mais j'ai pas trop le temps. Si personne ne l'a fait à mon retour je reprendrai ce post...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 26
    Par défaut
    Merci pour cette réponse ultra rapide

    J'ai essayé mais en ksh, le bash n'est pas dispo, mais il me sort l'erreur suivante :

    ./TEST.ksh[2]: 3: not found.

    Par rapport au script la seule chose qui change c'est celà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    #!/bin/ksh
    exec 3 </DVCC_data/VS/prm/TEMP-B
    exec 4 </DVCC_data/VS/prm/TEMP-A
    exec 5 >/DVCC_data/VS/prm/TEMP-C
    Autre question, celà ser à quoi "0"
    dans
    Par contre j'ai essayé cà et ca tourne en boucle mais ca passe

    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
     
    #!/bin/ksh
     
    # Lecture de ACCAD
    while read ligneB 
    do
        # Petit affichage de contrôle (facultatif mais ça montrera la progression)
        echo "$ligneB"
     
        # Lecture de A
        while read ligneA 
        do
            echo "$ligneA"
            # Extraction champ 1 de la ligne A
            c1=`echo $ligneA |cut -f1 -d,`
     
            # Si le champ 1 est dans la ligne B
            if echo $ligneB |grep "$c1" 1>/dev/null
            then
                 # On y rajoute le champ 2 de la ligne A
                 ligneB="$ligneB `echo $ligneA |cut -f2 -d,`"
            fi
        done <TEMP-A
     
        # On écrit la ligne finale dans C
        echo "$ligneB" 1>-C
    done <TEMP-B

    Par contre python n'est pas dispo, perl oui.

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 851
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par MarcCC Voir le message
    Merci pour cette réponse ultra rapide

    J'ai essayé mais en ksh, le bash n'est pas dispo, mais il me sort l'erreur suivante :

    ./TEST.ksh[2]: 3: not found.
    Erreur de ma part, faut pas d'espace entre "3" et "<" (j'ai rectifié mon code). Mais si ça ne marche toujours pas alors passe le script en "/bin/sh" et là ça marchera...

    Citation Envoyé par MarcCC Voir le message
    Autre question, celà ser à quoi "0"
    dans
    Tu rediriges l'entrée standard (le clavier) sur le contenu du flux n° 3 (le fichier B) donc l'info stockée dans "ligneB" sera prise à partir du flux 3 (le fichier) et celui-ci sera automatiquement vidé de ce qui a été lu. Donc "0" représente "le clavier". Inutile dans 95% des cas sauf quand il faut dire "quoi sera pris à partir d'un autre flux" (un peu comme "." est inutile dans 95% des cas sauf quand il faut explicitement nommer le répertoire local)

    Oups !!! En écrivant que le flux était automatiquement vidé, ça me fait penser que le flux 4 a aussi été vidé lors du traitement de la première ligne. Donc pour que ça marche complètement faut que tu décales le "exec 4<fichierA" sous le "do" du premier while (avant le "read ligneA"). J'ai aussi rectifié mon post...

    Citation Envoyé par MarcCC Voir le message
    Par contre j'ai essayé cà et ca tourne en boucle mais ca passe

    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/ksh
     
    # Lecture de ACCAD
    while read ligneB 
    do
        # Petit affichage de contrôle (facultatif mais ça montrera la progression)
        echo "$ligneB"
     
        # Lecture de A
        while read ligneA 
        do
            echo "$ligneA"
            # Extraction champ 1 de la ligne A
            c1=`echo $ligneA |cut -f1 -d,`
     
            # Si le champ 1 est dans la ligne B
            if echo $ligneB |grep "$c1" 1>/dev/null
            then
                 # On y rajoute le champ 2 de la ligne A
                 ligneB="$ligneB `echo $ligneA |cut -f2 -d,`"
            fi
        done <TEMP-A
     
        # On écrit la ligne finale dans C
        echo "$ligneB" 1>-C
    done <TEMP-B
    Bizarre que ça tourne en boucle !!! Car c'est aussi comme ça que j'aurais pu l'écrire sauf que je préfère utiliser les flux numérotés plutôt que les "< fic" mais c'est aussi une solution correcte...

    Citation Envoyé par MarcCC Voir le message
    Par contre python n'est pas dispo, perl oui.
    Désolé, je ne sais pas programmer en perl. Lorsque j'ai voulu apprendre un de ces deux langages j'ai choisi Python car plus récent...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 26
    Par défaut
    Ok merci celà fonctionne
    Par contre celà est très très long

    Le fichier A contient 11738 ligne et le B contient 488, soit en tout plus de 5 millions de passage

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 851
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par MarcCC Voir le message
    Le fichier A contient 11738 ligne et le B contient 488, soit en tout plus de 5 millions de passage
    Hé oui. C'est un peu le problème. T'aurais eu le contraire (à savoir A petit) t'aurais pu le stocker dans un tableau mais là, t'es coincé ou alors tu converti le programme en perl ou en C.

    Tu peux un peu optimiser le truc en introduisant un break intelligent si l'info de A est trouvée (ce qui signifie que tu ne cherches qu'une seule info parce que moi j'ai fait comme si la ligne de B pouvait contenir plusieurs infos de A) mais ce sera faible comme optimisation.
    T'as aucun moyen d'avoir Python ???
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. [système]shell + Nom de fichier avec Espace
    Par delphine_lep dans le forum Access
    Réponses: 3
    Dernier message: 23/03/2007, 16h24
  2. shell unix charger fichiers de variables
    Par waloo16 dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 31/01/2007, 17h29
  3. Réponses: 2
    Dernier message: 25/09/2006, 18h46
  4. Shell - Merge de fichiers
    Par tesla dans le forum Linux
    Réponses: 4
    Dernier message: 29/06/2004, 02h10
  5. Commande en shell -- Sur les fichiers
    Par OrangeBud dans le forum Linux
    Réponses: 8
    Dernier message: 18/05/2004, 13h13

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