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 :

SED - Supprimer 3 chiffres sur une colonne


Sujet :

Shell et commandes GNU

  1. #1
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 30
    Par défaut SED - Supprimer 3 chiffres sur une colonne
    Bonjour,

    J'ai un fichier texte avec des valeurs délimitées par des points-virgule :

    20130625;22;6150444466406;0810006033;AAA;10
    20130625;7;6330444441247;0238554590;PROSODIE;10
    20130625;113;0060444455226;0243954035;AAA;5
    20130625;3;0060444425231;0689793164;BBB;5
    20130625;33;0110444448015;0609750061;PROSODIE;14
    
    [...]
    Sur chaque ligne je voudrai supprimer les 3 premiers chiffres de la 3eme colonne. exemple le 615 :

    20130625;22;6150444466406;0810006033;AAA;10
    Je pensais utiliser la commande sed avec des regex, mais je ne maîtrise pas vraiment.

    J'ai testé sed -e 's/;[∗];;[∗];;[∗];$/\3/' sans résultats.

    Merci de m'aider

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

    Un truc comme ceci devrait fonctionner (pas testé):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed 's/;[0-9]\{,3\}/;/2'

  3. #3
    Membre actif
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Décembre 2012
    Messages : 43
    Par défaut
    j'ai plutot pensé 'awk'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    cat liste.txt | awk 'BEGIN { FS=";"; OFS=";" } {$3=substr($3,4,length($3));print $0}' > toto.txt
    fichier de départ : liste.txt
    fichier d'arrivée : toto.txt

  4. #4
    Invité
    Invité(e)
    Par défaut
    Pas besoin du cat et du lenght. Il suffit donc d'avoir ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk 'BEGIN { FS=";"; OFS=";" } {$3=substr($3,4);print $0}' liste.txt > toto.txt
    Ps: je confirme que la commande sed de disedorgue fonctionne

  5. #5
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 30
    Par défaut
    Bonjour,

    Merci à tous. J'ai juste testé la commande de disedorgue et elle fonctionne parfaitement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed 's/;[0-9]\{,3\}/;/2'
    Par contre pouvez-vous m'expliquer la commande étape par étape, car j'ai du mal à comprendre comment ça fonctionne?

  6. #6
    Invité
    Invité(e)
    Par défaut
    On remplace la partie commençant par ";" suivi de 3 chiffre max.
    [0-9] : chiffres de 0 à 9
    \{, 3\} : ce qu'il y a avant (donc les chiffres) doit être présent 0 à 3 fois

    On la remplace par un ";"
    Et on ne fait cette opération que sur la 2 ème occurrence trouvée (le 2 à la fin).

  7. #7
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 30
    Par défaut
    Du coup j'ai essayé d'adapter le code pour supprimer la 5eme colonne (AAA, PROSODIE etc.)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    line=`echo $line | sed 's/;[a-zA-Z]*/;/1'`
    Mais ça ne marche pas...

    Le 1 c'est bien pour dire que c'est la 1ere occurrence trouvée qui contient du [a-zA-Z]?

    J'ai essayé en remplaçant le 1 par du 5 au cas ou tu parlais des colonnes, mais pas de résultat non plus...

  8. #8
    Invité
    Invité(e)
    Par défaut
    Tu y étais presque.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    echo "20130625;22;6150444466406;0810006033;AAA;10" | sed 's/;[a-zA-Z]*/;/4'
    20130625;22;6150444466406;0810006033;;10
    Sauf que la 5ème colonne commence après le 4ème ";", donc il faut mettre le chiffre 4

    Sinon il faudrait mettre le ";" après le [a-zA-Z] et ça fonctionne aussi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo "20130625;22;6150444466406;0810006033;AAA;10" | sed 's/[a-zA-Z]*;/;/5'

  9. #9
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 408
    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 408
    Par défaut
    Question: Dans les exemples que tu donnes, on voit que la 5 éme colonne que tu veux supprimer, il n'y a que des lettres et toute les autres colonnes sont des exclusivement des chiffres, est-ce toujours le cas ?

    Si oui, tu peux simplifier par:
    Et aussi la version petit joueur pour la prise en compte des 2 cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -r 's/^(([^;]*;){2,2})[0-9]{3,3}([^A-Za-z]*)[A-Za-z]*/\1\3/'
    L'option -r de sed me sert ici pour écrire par exemple '(' au lieu de '\(' .
    Si besoin, je peux décrire comment elle fonctionne mais le mieux est d'essayer de la comprendre par soit même.

  10. #10
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 30
    Par défaut
    Merci beaucoup.


    A vrai dire je ne suis pas sûr d'utiliser la méthode la plus optimisée :

    j'ai une fonction comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function operateur() {
    case $1 in
    	AAA) operateur="1";;
    	BBB) operateur="2";;
        PROSODIE) operateur="3";;
    	*) operateur="4";;
    esac
    }

    Je supprime les lettres sur chaque lignes (while read line). Puis je termine comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    then echo "$line;$operateur;" >> $FICHOUT
    Y a t-il une commande plus optimisé que sed pour remplacer directement les opérateurs (AAA, BBB, Prosodie) par 1, 2 ou 3 ?

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

    En espérant avoir tout compris

    Pourquoi ne pas tout faire avec sed ?

    Le fichier de départ selon tes exemples :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ cat plop 
    20130625;22;6150444466406;0810006033;AAA;10
    20130625;7;6330444441247;0238554590;PROSODIE;10
    20130625;113;0060444455226;0243954035;AAA;5
    20130625;113;0060444455226;0243954035;AZF;5
    20130625;3;0060444425231;0689793164;BBB;5
    20130625;33;0110444448015;0609750061;PROSODIE;14
    20130625;113;0060444455226;0243954035;JHGT;15
    Le script sed (dans un fichier, beaucoup plus lisible) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ cat script.sed 
    s/;[0-9]\{,3\}/;/2
    s/AAA\(.*\)/\1;1/                      
    s/BBB\(.*\)/\1;2/                      
    s/PROSODIE\(.*\)/\1;3/                 
    s/;[a-zA-Z]\+\(.*\)/;\1;4/
    L'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ sed -f script.sed plop 
    20130625;22;0444466406;0810006033;;10;1
    20130625;7;0444441247;0238554590;;10;3
    20130625;113;0444455226;0243954035;;5;1
    20130625;113;0444455226;0243954035;;5;4
    20130625;3;0444425231;0689793164;;5;2
    20130625;33;0444448015;0609750061;;14;3
    20130625;113;0444455226;0243954035;;15;4
     
    $

  12. #12
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 408
    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 408
    Par défaut
    Citation Envoyé par zipe31 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ cat script.sed 
    s/;[0-9]\{,3\}/;/2
    s/AAA\(.*\)/\1;1/                      
    s/BBB\(.*\)/\1;2/                      
    s/PROSODIE\(.*\)/\1;3/                 
    s/;[a-zA-Z]\+\(.*\)/;\1;4/
    Ici, il serait plus prudent de mettre les délimiteurs pour les remplacements spécifiques (AAA,BBB,PROSODIE) car rien ne dit que l'on ne peut pas avoir par exemple CBBBTITI.

    @shonan: Sinon, si ce n'est pas ce que tu veux, peut-être que le plus simple serait de nous montrer un input et un output final

  13. #13
    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
    Citation Envoyé par disedorgue Voir le message
    Ici, il serait plus prudent de mettre les délimiteurs pour les remplacements spécifiques (AAA,BBB,PROSODIE) car rien ne dit que l'on ne peut pas avoir par exemple CBBBTITI.
    C'est clair. Par contre maintenant j'ai pour habitude de donner une solution en fonction de la demande. Plus la demande est étoffée (exemples précis avant/après), plus la solution sera élaborée, dans le cas contraire je donne du générique.

  14. #14
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 408
    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 408
    Par défaut
    On est d'accord sur ce point...

    Sinon, voici une version pure shell (bash):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ cat xxef
    20130625;22;6150444466406;0810006033;AAA;10
    20130625;7;6330444441247;0238554590;PROSODIE;10
    20130625;113;0060444455226;0243954035;AAA;5
    20130625;113;0060444455226;0243954035;AZF;5
    20130625;3;0060444425231;0689793164;BBB;5
    20130625;33;0110444448015;0609750061;PROSODIE;14
    20130625;113;0060444455226;0243954035;JHGT;15
    20130625;;0060444485426;0243994035;AAAA;15
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    while IFS=';' read a b c d e f
    do
     case $e in
      AAA) o="1";;
      BBB) o="2";;
      PROSODIE) o="3";;
      *) o="4";;
     esac
     echo "$a;$b;${c/[0-9][0-9][0-9]/};$d;;$f;$o"
    done <xxef
    ce qui donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    20130625;22;0444466406;0810006033;;10;1
    20130625;7;0444441247;0238554590;;10;3
    20130625;113;0444455226;0243954035;;5;1
    20130625;113;0444455226;0243954035;;5;4
    20130625;3;0444425231;0689793164;;5;2
    20130625;33;0444448015;0609750061;;14;3
    20130625;113;0444455226;0243954035;;15;4
    20130625;;0444485426;0243994035;;15;4

Discussions similaires

  1. Réponses: 2
    Dernier message: 26/05/2014, 14h48
  2. [XL-2003] Supprimer une règle sur une colonne
    Par audrey1912 dans le forum Excel
    Réponses: 3
    Dernier message: 23/11/2012, 15h16
  3. Mettre tous les chiffres en indices sur une colonne
    Par ledisciple dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 30/08/2011, 16h29
  4. Trigger sur une colonne ?
    Par hpalpha dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 22/03/2004, 15h16
  5. Check sur une colonne de table "en cours"
    Par in dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 02/07/2003, 10h47

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