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 :

Lire ou Substituer une valeur dans un CSV d'après son abscisse ordonnée


Sujet :

Shell et commandes GNU

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 25
    Par défaut Lire ou Substituer une valeur dans un CSV d'après son abscisse ordonnée
    Bonjour,

    Et bien voilà tout est dit, je cherche une méthode pour lire ou renvoyer la valeur d'une coordonnée "X,Y" dans un CSV

    Pour l'instant je me débrouille avec quelques lignes de KSH
    je sors la ligne avec sed, puis le champs avec cut
    Et éventuellement je substitue avant de renvoyer la ligne complète en écrasant la précédente toujours avec sed


    Mais je me demande s'il n'y a pas une méthode plus rapide en terme de CPU et surtout de lisibilité en pur sed ou awk
    Les possibilités sont nombreuses avec ces 2 outils mais je n'ai pas trouvé une qui conviendrait en fournissant directement l'abscisse et l'ordonnée (voire mieux la clé de ligne et de colonne !)

    S'il y a des amoureux de sed/awk par ici..

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 703
    Par défaut
    Bonjour,

    s'il y a un échantillon de fichier... par ici !

    par la même occasion, affiche le résultat attendu.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 25
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    HOSTNAME;IP;LABEL;LAST_UPDATE
    serveur1;192.168.0.1;web server;2017-05-02
    serveur2;192.168.0.2;ftp server;2017-06-02
    serveur3;192.168.0.3;ntp server;2017-01-02
    Par exemple pour lire :
    read_csv "LABEL" "serveur2"
    me renverrait "ftp server"


    Ou écrire :
    write_csv "LABEL" "serveur2" "ldap server"
    modifierait ce champs


    Si c'est pas possible avec les clés, je serais déjà très content si je pouvais obtenir ce résultat rien qu'avec les index (3 3 dans le cas présent)

  4. #4
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 397
    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 397
    Par défaut
    Bonjour,

    Ce n'est pas impossible avec les clés, mais il y a une petite incohérence:
    On comprend bien que les clés sont la première ligne de ton fichier, donc:
    HOSTNAME
    IP
    LABEL
    LAST_UPDATE

    Mais dans tes commandes read_csv et wrtite_csv que représente le 2ème paramètre ?
    Obligatoirement la clé HOSTNAME ?

    Pas clair...

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Par défaut
    Bonjour,
    J'ai pas testé avec l'échantillon mais peut être avec ça ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #!/bin/sh
    #colonne=$1
    #ligne=$2
    #nouvelle_valeur=$3
    #file=$4
    A=truc_improbable
    sed $2'{s/;/'"$A$3"';/'"$1"';s/;/'"$A"'/'"$(($1-1))"';s/'"$A"'.*'"$A"'/;/}' "$4"
    cordialement.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 25
    Par défaut
    disedorgue > Oui c'est obligatoirement la 1ère colonne, les clés sont forcément la 1ère colonne et la 1ère ligne, et je veux lire ou modifier la valeur à leur intersection.

    ctac_ > ta ligne me fait flipper, mais fonctionne à merveille avec les index
    Tu peux m'expliquer dans les grandes lignes la logique de ton script sed ?

    Tu aurais une version qui renvoie juste le contenu de la cellule?
    Et une qui fonctionne à partir des clés (soyons fou)



    Ils font des bouquins entiers sur sed... L'investissement en temps est conséquent mais je pense que dans notre métier bien maitriser sed et awk peuvent rendre bien des services pour ne pas avoir à partir dans du perl ou python

  7. #7
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 397
    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 397
    Par défaut
    Un exemple en awk, qui récupère le n° du champs sur la première ligne:

    Fichier exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ cat /tmp/plop
    HOSTNAME;IP;LABEL;LAST_UPDATE
    serveur1;192.168.0.1;web server;2017-05-02
    serveur2;192.168.0.2;ftp server;2017-06-02
    serveur3;192.168.0.3;ntp server;2017-01-02
    Partie read_csv:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ awk -F\; -vColKey="LABEL" -vLineKey="serveur2" 'NR == 1 {while(++i<=NF){if($i==ColKey){next}}};$1 == LineKey {print $i}' /tmp/plop
    ftp server
    Partie write_csv:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ awk -F\; -vColKey="LABEL" -vLineKey="serveur2" -vValue="ldap server" 'NR == 1 {while(++i<=NF){if($i==ColKey){print;next}}};$1 == LineKey {OFS=FS;$i=Value}1' /tmp/plop
    HOSTNAME;IP;LABEL;LAST_UPDATE
    serveur1;192.168.0.1;web server;2017-05-02
    serveur2;192.168.0.2;ldap server;2017-06-02
    serveur3;192.168.0.3;ntp server;2017-01-02
    Attention: awk ne permet pas de modifier directement le fichier, donc pour le write_csv, il faut passer par un fichier temporaire.

  8. #8
    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,

    Citation Envoyé par disedorgue Voir le message
    Attention: awk ne permet pas de modifier directement le fichier, donc pour le write_csv, il faut passer par un fichier temporaire.
    Si, si il peut. Depuis la version 4.1.0 de gawk

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Par défaut
    OK pour une petite explication mais il est préférable d'utiliser la solution de disedorgue avec awk car ma proposition ne fonctionne pas pour les première et dernière colonnes.
    donc :
    on ne s'occupe avec sed que de la ligne passé en paramètre $2
    commande 1 : On remplace le ; de la colonne passé en paramètre $1 par truc_improbable suivie de la nouvelle valeur passé en paramètre $3 suivie de ;
    Les ' sont pour sed et les " sont pour le shell pour qu'il interprète les variables.
    Les ; permettent de séparer les commandes.
    commande 2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s/;/'"$A"'/'"$(($1-1))"'
    On remplace le ; de la colonne -1 $(($1-1)) par truc_improbable pour faire un repère.
    commande 3 : On remplace les deux repères truc_improbable et ce qui se trouve entre qui correspond justement a ce qu'on veux remplacer par ;
    J'espère que c'est assez clair.
    Cordialement.

  10. #10
    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,
    Citation Envoyé par ctac_ Voir le message
    OK pour une petite explication mais il est préférable d'utiliser la solution de disedorgue avec awk car ma proposition ne fonctionne pas pour les première et dernière colonnes.
    Pour remplacer le champ 3, cela devrait suffire :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ sed '/^serveur2/ s/[^;]*/ldap server/3' fich 
    HOSTNAME;IP;LABEL;LAST_UPDATE
    serveur1;192.168.0.1;web server;2017-05-02
    serveur2;192.168.0.2;ldap server;2017-06-02
    serveur3;192.168.0.3;ntp server;2017-01-02

  11. #11
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Par défaut
    Ok, nettement meilleur et pas de problème de colonne.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed $2's/[^;]*/'"$3"'/'"$1" "$4"
    Cordialement.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 25
    Par défaut
    Citation Envoyé par ctac_ Voir le message
    Ok, nettement meilleur et pas de problème de colonne.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed $2's/[^;]*/'"$3"'/'"$1" "$4"
    Cordialement.

    Sur celle là, il me dit option inconnue pour s

Discussions similaires

  1. Réponses: 10
    Dernier message: 13/07/2012, 10h39
  2. Lire une valeur dans ma bdd, et une erreur inutile !
    Par Dr_shaman dans le forum VB.NET
    Réponses: 3
    Dernier message: 04/11/2008, 17h06
  3. Lire une valeur dans une spinbox
    Par arknouf dans le forum Qt
    Réponses: 3
    Dernier message: 21/04/2008, 17h52
  4. Lire et créer une valeur dans le registre
    Par bilal_inf dans le forum Langage
    Réponses: 3
    Dernier message: 11/05/2007, 19h11
  5. Lire une valeur dans le registre
    Par John.s dans le forum C
    Réponses: 2
    Dernier message: 26/11/2003, 20h55

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