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 :

Ajouter ou mettre à jour des éléments d'un fichier A vers un fichier B


Sujet :

Shell et commandes GNU

  1. #1
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut Ajouter ou mettre à jour des éléments d'un fichier A vers un fichier B
    Bonjour,

    J'ai le fichier A :

    user1:password:901:100:Prenom Nom:/home/user1:/bin/ksh
    user2:password:902:100:Prenom Nom:/home/user2:/bin/ksh
    user3:password:903:100:Prenom Nom:/home/user3:/bin/ksh
    user4:password:904:100:Prenom Nom:/home/user4:/bin/ksh
    user5:password:905:100:Prenom Nom:/home/user5:/bin/ksh
    Puis un fichier B :

    user6:password:901:100:Prenom Nom:/home/user6:/bin/ksh
    user7:password:902:100:Prenom Nom:/home/user7:/bin/ksh
    user3:password:903:100:Prenom Nom:/home/user3:/bin/ksh
    user9:password:904:100:Prenom Nom:/home/user9:/bin/ksh
    user5:password:905:100:Prenom Nom:/home/user5:/bin/ksh
    J'aimerai à partir du fichier A, mettre à jours les informations du fichier B :

    1. Si une ligne du fichier A n'existe pas dans le fichier B, je l'ajoute à la suite.
    2. Si une ligne du fichier A est différente d'une ligne du fichier B, je mets à jour.

    Sachant que la la clé unique entre les deux fichiers est la 1er colonne (userXX)

    Comment faire cela en bash (avec une base de donnée cela aurai été trop facile :cry:)

    Encore merci d'avance pour vos indications

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    bonjour,

    c'est tout bête : "yaka" utiliser sort avec les bonnes options (unicité, clé) sur les deux fichiers en même temps, que tu mets dans une substitution de commande, pour en faire un echo redirigé vers le fichier B...
    ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Expert éminent sénior Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Points : 12 264
    Points
    12 264
    Par défaut
    quand au passage d'une machine a l'autre c'est tres simple tu peux tuiliser "-" pour des accès directs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     echo toto | ssh -l operateur undertaker " cat - > t"
    bien sur tu peux aussi tout simplement faire un scp
    mais attention aux effets de bord au moment de l'ecriture du fichier

  4. #4
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    Merci pour vos réponses, mais... je n'est pas trop compris votre manière de faire

  5. #5
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 70
    Points : 99
    Points
    99
    Par défaut
    Tu peux faire :
    cat fichier1 fichier2 | sort -u | uniq

    Mais parfois quelques doublons restent (je ne saurai pas dire pourquoi)

  6. #6
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    merci pour ta réponse. cela fonctionne bien.

    Cependant,...


    Dans chaque fichier, l'identifiant unique est la 1er colonne (users). Imaginons que l'on change certains paramètres à cette utilisateur. Si j'utilise ta méthode, mon utilisateur sera en double. Le but est de mettre à jour ces paramètres.

    Avec awk, il y a pas moyen de faire cela ?

  7. #7
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 70
    Points : 99
    Points
    99
    Par défaut
    La seule chose que je suis en mesure de proposer, c'est de rechercher dans les options de sort et uniq, afin de limiter la comparaison aux X premiers bit de chaque ligne et, ainsi, de limiter la comparaison à ton champ user...

  8. #8
    Membre confirmé
    Avatar de argoet
    Inscrit en
    Mai 2002
    Messages
    582
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 582
    Points : 562
    Points
    562
    Par défaut
    En vous inspirant peut etre de ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #!/bin/ksh 
    /bin/rm C
    touch C
    for i in `cat A B | cut -d":" -f1 | sort | uniq`
    do
        Lig=`grep ^$i: A`
        echo "$i($Lig)"
        if [ "$Lig" != "" ] 
        then 
           echo $Lig >> C
        else
           grep ^$i: B >> C
        fi
    done
    Signé : Capitaine Jean-Luc Picard

  9. #9
    Membre confirmé
    Avatar de argoet
    Inscrit en
    Mai 2002
    Messages
    582
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 582
    Points : 562
    Points
    562
    Par défaut
    A
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    user1:password:901:100:Prenom Nom:/home/user1:/bin/ksh
    user2:password:902:100:Prenom Nom:/home/user2:/bin/ksh
    user3:password:903:100:Prenom Nom:/home/repd3:/bin/ksh
    user4:password:904:100:Prenom Nom:/home/user4:/bin/ksh
    user5:password:905:100:Prenom Nom:/home/user5:/bin/ksh
    B
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    user6:password:901:100:Prenom Nom:/home/user6:/bin/ksh
    user7:password:902:100:Prenom Nom:/home/user7:/bin/ksh
    user3:password:903:100:Prenom Nom:/home/user3:/bin/ksh
    user9:password:904:100:Prenom Nom:/home/user9:/bin/ksh
    user5:password:905:100:Prenom Nom:/home/user5:/bin/ksh
    Donne C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    user1:password:901:100:Prenom Nom:/home/user1:/bin/ksh
    user2:password:902:100:Prenom Nom:/home/user2:/bin/ksh
    user3:password:903:100:Prenom Nom:/home/repd3:/bin/ksh
    user4:password:904:100:Prenom Nom:/home/user4:/bin/ksh
    user5:password:905:100:Prenom Nom:/home/user5:/bin/ksh
    user6:password:901:100:Prenom Nom:/home/user6:/bin/ksh
    user7:password:902:100:Prenom Nom:/home/user7:/bin/ksh
    user9:password:904:100:Prenom Nom:/home/user9:/bin/ksh
    Signé : Capitaine Jean-Luc Picard

  10. #10
    Membre confirmé
    Avatar de argoet
    Inscrit en
    Mai 2002
    Messages
    582
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 582
    Points : 562
    Points
    562
    Par défaut
    Plus simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #!/bin/ksh 
    /bin/rm C
    touch C
    for i in `cat A B | cut -d":" -f1 | sort | uniq`
    do
        # A est prioritaire sur B
        grep -h ^$i: A B | head -1 >> C
    done
    Signé : Capitaine Jean-Luc Picard

  11. #11
    Membre confirmé
    Avatar de argoet
    Inscrit en
    Mai 2002
    Messages
    582
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 582
    Points : 562
    Points
    562
    Par défaut
    Si B est prioritaire sur A
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #!/bin/ksh 
    /bin/rm C
    touch C
    for i in `cat A B | cut -d":" -f1 | sort | uniq`
    do
        # B est prioritaire sur A
        grep -h ^$i: B A | head -1 >> C
    done
    donne C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    user1:password:901:100:Prenom Nom:/home/user1:/bin/ksh
    user2:password:902:100:Prenom Nom:/home/user2:/bin/ksh
    user3:password:903:100:Prenom Nom:/home/user3:/bin/ksh
    user4:password:904:100:Prenom Nom:/home/user4:/bin/ksh
    user5:password:905:100:Prenom Nom:/home/user5:/bin/ksh 
    user6:password:901:100:Prenom Nom:/home/user6:/bin/ksh
    user7:password:902:100:Prenom Nom:/home/user7:/bin/ksh
    user9:password:904:100:Prenom Nom:/home/user9:/bin/ksh
    Signé : Capitaine Jean-Luc Picard

  12. #12
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    Merci d'avance, je vais essayer vos propositions.

  13. #13
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo "$(sort -t':' -u -k1,1 fic{A,B})" > ficB
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep -vf ficB ficA >> ficB
    fonctionne aussi, mais cela prend en compte des lignes entières, contrairement à la première solution, qui, elle, ne considère, effectivement que le premier champ.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  14. #14
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    On ne peux pas écrire dans un fichier qu'on est en train de lire. Ca marchera peut-être pour des petits fichiers qui tiennent intégralement dans le buffer, mais il y a toujours une taille à partir de laquelle on se retrouvera avec un fichier vide ou corrompu.

    Bref il faut soit utiliser un fichier temporaire, soit ruser avec un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    exec <ficB
    rm ficB
    { cat ficA; cat; } | sort -t':' -u -k1,1 > ficB

  15. #15
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    peut-être pour le grep, mais ça devrait fonctionner correctement avec la substitution de commande, puisqu'elle est évaluée avant d'être affichée par echo pour être redirigée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    resultat=$(sort -t':' -u -k1,1 fic{A,B})
    echo "$resultat" > ficB
    c'est pareil, sauf qu'ici, on utilise une variable intermédiaire superflue.

    par contre, ta ruse ne fonctionne pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ exec 3<ficB
    $ cat ficB
    user6:password:901:100:Prenom Nom:/home/user6:/bin/ksh
    user7:password:902:100:Prenom Nom:/home/user7:/bin/ksh
    user3:password:903:100:Prenom Nom:/home/user3:/bin/ksh
    user9:password:904:100:Prenom Nom:/home/user9:/bin/ksh
    user5:password:905:100:Prenom Nom:/home/user5:/bin/ksh
    $ echo blah > ficB
    $ cat <&3
    blah
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  16. #16
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 434
    Points : 654
    Points
    654
    Par défaut
    Informe toi sur la commande sed

  17. #17
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    N_BaH d'accord pour le echo.

    La "ruse" sert à écrire dans le fichier qu'on lit sans passer par un fichier temporaire. Je ne comprend pas ce que tu essayais de faire avec ton test. Plus simplement ça consiste à faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    exec <fichier
    rm fichier
    Commande_qui_lit_le_contenu_de_fichier_sur_stdin > fichier
    Ce qui fonctionne, parce que le > recréé un fichier qui a le même nom que le fichier original, mais qui est en fait un différent fichier (inode différent). Et la lecture du contenu de fichier est toujours possible parce qu'on avait un fd en lecture sur ce fichier au moment du rm.

  18. #18
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    ah, d'accord ! il ne s'agit pas de dupliquer le descripteur de fichier, mais d'utiliser ce qui s'affiche sur la sortie standard :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #!/bin/bash
     
    exec <ficB
    cat ficA - | sort -t':' -u -k1,1 > ficB
    NB: tapé sur la ligne de commande, ça ne marchait pas, et provoquait un exit
    sur la ligne de commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    (exec <ficB; cat ficA - | sort -t':' -u -k1,1 > ficB)
    cat ficB
    user1:password:901:100:Prenom Nom:/home/user1:/bin/ksh
    user2:password:902:100:Prenom Nom:/home/user2:/bin/ksh
    user3:password:903:100:Prenom Nom:/home/user3:/bin/ksh
    user4:password:904:100:Prenom Nom:/home/user4:/bin/ksh
    user5:password:905:100:Prenom Nom:/home/user5:/bin/ksh
    user6:password:901:100:Prenom Nom:/home/user6:/bin/ksh
    user7:password:902:100:Prenom Nom:/home/user7:/bin/ksh
    user9:password:904:100:Prenom Nom:/home/user9:/bin/ksh
    ne me déconnecte plus
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

Discussions similaires

  1. [OL-2007] Mettre à jour des éléments dans un contact
    Par gambi dans le forum Outlook
    Réponses: 0
    Dernier message: 12/01/2013, 13h14
  2. Mettre à jour des tables avec un trigger
    Par Titouf dans le forum Langage SQL
    Réponses: 9
    Dernier message: 20/01/2008, 15h57
  3. [Hibernate] mise à jour des éléments des détails
    Par neuromencien dans le forum Hibernate
    Réponses: 9
    Dernier message: 16/02/2007, 14h47
  4. Mettre à jour des champs dans un sous formulaire
    Par Patros dans le forum Access
    Réponses: 3
    Dernier message: 09/08/2006, 15h16
  5. Mettre à jour des champs suite à un RecordSet
    Par Miss Ti dans le forum Access
    Réponses: 3
    Dernier message: 25/07/2006, 22h43

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