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 :

Script SED ou AWK qui remplace la valeur d'un attribut par la valeur d'un autre attribut


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2019
    Messages : 7
    Par défaut Script SED ou AWK qui remplace la valeur d'un attribut par la valeur d'un autre attribut
    Bonjour,

    J'ai beaucoup cherché, sans trouver de solution; avant de demander de l'aide en ligne.
    Voila mon problème :
    Je cherche à remplacer la valeur d'un attribut dans un fichier par la valeur d'un autre attribut.
    Précision : le fichier en question, pour ceux qui connaissent, est un fichier de type "ldif" (extension .ldif), fichier qui contient par exemple, la liste des utilisateurs ldap avant l'intégration à ldap.

    Le fichier est constitué comme ce-ci :

    .....

    DN: uid:jean.valjean,ou=Users,dc=local,dc=com
    uid: jean.valjean
    mail: jean.vlajean@local.com
    gecos: gnagnagna

    DN: uid:jean.paul,ou=Users,dc=local,dc=com
    uid: jean.paul
    mail: jean.paul@local.com
    gecos: gnignigni

    .....

    Et il est constitué de X paragraphes avec à peut près la même structure.. je dis a peut près car des fois l'attribut gecos est avant l'attribut mail..

    Ce que je veux faire en faite c'est de remplacer la valeur de l'attribut mail par la valeur de l'attribut gecos.
    En gros sur l'exemple précédent j'aimerai obtenir :

    .....

    DN: uid:jean.valjean,ou=Users,dc=local,dc=com
    uid: jean.valjean
    mail: gnagnagna
    gecos: gnagnagna

    DN: uid:jean.paul,ou=Users,dc=local,dc=com
    uid: jean.paul
    mail: gnignigni
    gecos: gnignigni

    .....

    j'ai trouvé le moyen d'extraire chacune des valeur.. mais pour le remplacement je n'y arrive pas..
    Quelqu'un aurait une idée ? je pense que avec SED ou AWK ça doit être possible mais j'avoue que je sèche...

    EDIT :

    J'ai trouvé un moyen pas très propre mais qui se tiens pour le moment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e '/./{H;$!d;}' -e 'x;/gecos/!d;' /etc/ldap/test/fichier.ldif | sed /mail/d | sed s/gecos/mail/g
    Ce qui donne :
    .....

    DN: uid:jean.valjean,ou=Users,dc=local,dc=com
    uid: jean.valjean
    mail: gnagnagna

    DN: uid:jean.paul,ou=Users,dc=local,dc=com
    uid: jean.paul
    mail: gnignigni

    .....

    Si quelqu'un à une meilleure idée..

  2. #2
    Expert confirmé
    Avatar de becket
    Profil pro
    Informaticien multitâches
    Inscrit en
    Février 2005
    Messages
    2 854
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Informaticien multitâches
    Secteur : Service public

    Informations forums :
    Inscription : Février 2005
    Messages : 2 854
    Par défaut
    Salut

    C'est l'histoire d'une ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    awk ' BEGIN { RS="DN:" } {  print gensub("(.*)(mail:)(.*)\n(gecos:)(.*)\n","RS:\\1\\2\\5\\4\\5","g")   } ' fichier.ldif

  3. #3
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2019
    Messages : 7
    Par défaut
    Citation Envoyé par becket Voir le message
    Salut

    C'est l'histoire d'une ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    awk ' BEGIN { RS="DN:" } {  print gensub("(.*)(mail:)(.*)\n(gecos:)(.*)\n","RS:\\1\\2\\5\\4\\5","g")   } ' fichier.ldif
    Alors j'ai testé ton code, effectivement c'est pas mal, mais ça ne marchera pas en production.
    C'est de ma faute je n'ai pas été assez précis :
    entre mail et gecos il y a plein d'attributs à la con, du style :
    objectClass: person
    objectClass: organizationalPerson
    objectClass: inetOrgPerson
    objectClass: posixAccount
    objectClass: top
    objectClass: shadowAccount
    shadowLastChange: 15686
    loginShell: /bin/false
    uidNumber: 2222

    Ta commande est bien mais elle écrase tous les attributs qu'il y a entre mail et gecos.
    Mais c'est moi qui n'ai pas été assez précis.

  4. #4
    Expert confirmé
    Avatar de becket
    Profil pro
    Informaticien multitâches
    Inscrit en
    Février 2005
    Messages
    2 854
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Informaticien multitâches
    Secteur : Service public

    Informations forums :
    Inscription : Février 2005
    Messages : 2 854
    Par défaut
    Effectivement ....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      print gensub("(.*)(mail:)(.*)\n(.*)\n(gecos:)(.*)\n","RS:\\1\\2\\6\\3\\5\\6","g")

    Pour y arriver, suffit de rajouter la recopie de cette partie la ( j'ai pas testé le code )

  5. #5
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2019
    Messages : 7
    Par défaut
    Je vais tester, ça m'a l'air vraiment pas mal.
    "RS:\\1\\2\\6\\3\\5\\6","g")
    Cette partie veux dire quoi ? je suis nul en AWK

  6. #6
    Expert confirmé
    Avatar de becket
    Profil pro
    Informaticien multitâches
    Inscrit en
    Février 2005
    Messages
    2 854
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Informaticien multitâches
    Secteur : Service public

    Informations forums :
    Inscription : Février 2005
    Messages : 2 854
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    awk ' BEGIN { RS="DN:" } {  print gensub("(.*)(mail:)(.*)\n(gecos:)(.*)\n","RS:\\1\\2\\5\\4\\5","g")   } ' fichier.ldif
    Le plus simple est d'expliquer toute la commande

    RS="DN:"

    Le début d'un enregistrement commence par DN:. Cela permet de travailler sur des enregistrements et pas sur des "lignes".

    - gensub permet de faire du chercher/remplacer sur une chaine de caractère ( ici sur $0 qui correspond à l'enregistrement au complet )
    - () permet de mettre dans un tampon 1 - 2 -3 une partie de la chaine ( les \\1 \\2 )
    - . n'importe quel caractère
    - * répétition 0 ou +
    => .* n'importe quel caractère répété 0 ou plus



    Ce qui donne pour le début :

    (.*)(mail(.*)\n

    Après le séparateur : tu prends tous les caractères jusqu'a 'mail:' et tu mets le tout dans un tampon 1 :
    Tu mets mail: dans le tampon 2 ( ce n'est pas obligatoire )
    Tu mets tous entre mail: et le retour à la ligne (\n) dans le tampon 3

    ... etc etc


    Une fois la chaine découpé tu remplaces cette chaines par RS: et la série de tampon que l'on a pris juste avant

    RS:\\1\\2\\5\\4\\5

  7. #7
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2019
    Messages : 7
    Par défaut
    Très intéressant, il faut vraiment que je prenne des cours perso sur AWK qui m'a l'air vraiment puissant et qui peut répondre à pas mal de problématiques. Merci en tout cas pour ces explications.

  8. #8
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 347
    Par défaut
    Bonjour,

    Dans ton résultats, on voit que tu n'as plus l'attribut gecos, donc c'est hyper simple:
    tu vires les lignes d'attribut mail et tu change le mot "gecos" par mail et si tu veux aussi garder gecos, bah tu dupliques la ligne gecos.

  9. #9
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2019
    Messages : 7
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Bonjour,

    Dans ton résultats, on voit que tu n'as plus l'attribut gecos, donc c'est hyper simple:
    tu vires les lignes d'attribut mail et tu change le mot "gecos" par mail et si tu veux aussi garder gecos, bah tu dupliques la ligne gecos.
    Oui, si tu regarde mon post, j'avais fait un EDIT parce que effectivement j'avais trouvé cette solution :

    EDIT :

    J'ai trouvé un moyen pas très propre mais qui se tiens pour le moment :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e '/./{H;$!d;}' -e 'x;/gecos/!d;' /etc/ldap/test/fichier.ldif | sed /mail/d | sed s/gecos/mail/g
    Ce qui donne :
    .....

    DN: uid:jean.valjean,ou=Users,dc=local,dc=com
    uid: jean.valjean
    mail: gnagnagna

    DN: uid:jean.paul,ou=Users,dc=local,dc=com
    uid: jean.paul
    mail: gnignigni

    .....

    Si quelqu'un à une meilleure idée..
    En réalité je pense que je vais retenir cette solution qui, au final, est beaucoup plus simple.
    En tout cas merci à vous deux, si vous avez d'autres idées je suis toujours preneur !

  10. #10
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 347
    Par défaut
    Ok, mais ta ligne me parait bien compliqué, quelque chose comme ceci est suffisant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e '/^mail:/d' -e '/gecos/s/gecos/mail/' fichier.ldiff
    Et si tu veux garder la ligne gecos:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e '/^mail:/d' -e '/gecos/s/gecos\(.*\)/mail\1\n&/' fichier.ldiff

  11. #11
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2019
    Messages : 7
    Par défaut
    Oui ça marche aussi mais en faite pour être plus précis, le début de la commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e '/./{H;$!d;}' -e 'x;/gecos/!d;' /etc/ldap/test/fichier.ldif
    ça va me permettre de filtrer par groupe.
    Au final ce sera un truc du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e '/./{H;$!d;}' -e 'x;/groupe 1/!d;' /etc/ldap/test/fichier.ldif | sed /mail/d | sed s/gecos/mail/g
    si je fais le code que tu m'as proposé il va le faire pour tous le monde et ce n'est pas forcément ce que je veux.

    Ce début de commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e '/./{H;$!d;}' -e 'x;/groupe 1/!d;' /etc/ldap/test/fichier.ldif
    permet en faite d'isoler les paragraphes qui contiennent le groupe 1.
    D'ailleur si tu es bon en SED j'aurai bien voulu trouver une explication de cette commande notamment -e '/./{H;$!d;}' Que je n'arrive pas à décrypter. Je l'ai trouvé sur le net mais ça fonctionne super bien.

  12. #12
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 347
    Par défaut
    Citation Envoyé par Axtiz Voir le message
    si je fais le code que tu m'as proposé il va le faire pour tous le monde et ce n'est pas forcément ce que je veux.

    Ce début de commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e '/./{H;$!d;}' -e 'x;/groupe 1/!d;' /etc/ldap/test/fichier.ldif
    permet en faite d'isoler les paragraphes qui contiennent le groupe 1.
    D'ailleur si tu es bon en SED j'aurai bien voulu trouver une explication de cette commande notamment -e '/./{H;$!d;}' Que je n'arrive pas à décrypter. Je l'ai trouvé sur le net mais ça fonctionne super bien.
    Dans ce cas, je comprend mieux...

    Sinon, /./{H,$!d;} prend toutes les ligne non vides et les place dans le 'hold space' tout en l'effaçant si ce n'est pas la dernière ligne et on passe à la ligne suivante:
    /./ ==> ligne non vide
    H ==> placer la ligne dans le 'hold space'
    $ ==> dernière ligne ?
    ! ==> negation
    d ==> efface la ligne et on recommence le cycle avec la ligne suivante

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 12/01/2019, 23h20
  2. [OpenOffice][Tableur] Remplacement d'un contenu de cellule par le contenu d'une autre cellule
    Par jess8931 dans le forum OpenOffice & LibreOffice
    Réponses: 4
    Dernier message: 23/04/2017, 17h38
  3. Réponses: 7
    Dernier message: 08/01/2013, 18h33
  4. Liste deroulante qui modifie les valeurs de plusieur autres listes
    Par luan220 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 10/08/2008, 19h06
  5. Script avec sed et awk
    Par arezki76 dans le forum Shell et commandes GNU
    Réponses: 15
    Dernier message: 04/01/2007, 14h56

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