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] Remplacement dans des blocs de commentaires


Sujet :

Shell et commandes GNU

  1. #1
    Membre très actif
    Profil pro
    ingénieur
    Inscrit en
    Novembre 2011
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Novembre 2011
    Messages : 165
    Par défaut [sed] Remplacement dans des blocs de commentaires
    Bonjour à tous,

    j'ai un script à écrire qui regarde dans des fichiers de code C pour modifier les blocs de commentaires:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      /* vous \340 vous */
    printf("bonjour \340 vous");
    devient:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      /* bonjour à vous */
    printf("bonjour \340 vous");
    J'ai tenté des choses du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -i 's+$[ \t]*/\*.\340.+$[ \t]*/\*.à.+g' $mon_fichier
    (plus un milliard d'autres essais) mais absolument rien de fonctionne :/

    Des idées svp?

  2. #2
    Membre Expert Avatar de Ivelios
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    1 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 031
    Par défaut
    Bonjour,

    Quelque chose comme ça?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -i 's#/\*\(.*\)\\340\(.*\)\*/#/*\1à\2*/#g' monfichier

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

    Est-ce que la finalité, et la subtilité, est de reprendre dans le commentaire le contenu du "printf" ? Ou pas du tout ?

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par Ivelios Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -i 's#/\*\(.*\)\\340\(.*\)\*/#/*\1à\2*/#g' monfichier
    Chez moi (Ubuntu 12.04), ça ne marche pô!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ echo -e "/* bonjour \0340 vous */" | od -c
    0000000   /   *       b   o   n   j   o   u   r     340       v   o   u
    0000020   s       *   /  \n
    0000025
     
    $ echo -e "/* bonjour \0340 vous */"
    /* bonjour � vous */
     
    $ echo -e "/* bonjour \0340 vous */" | sed 's#/\*\(.*\)\\340\(.*\)\*/#/*\1A\2*/#g'
    /* bonjour � vous */
    De plus, s'il y a plusieurs '\340', ça n'en remplacera (au mieux) qu'un seul!

    Il vaudrait probablement mieux utiliser un sed avec matching... mais j'y arrive pô:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ echo -e "/* bonjour \0340 vous */" | sed '/\/\*.*\*\//s/o/O/g' # Pour voir
    /* bonjour � vous */
     
    $ echo -e "/* bonjour \0340 vous */" | sed '/\/\*\(.\|\\340\)*\*\//s/o/O/g'
    /* bonjour � vous */
    Apparemment, vu où sed insère le 'XXX', '.' ne matche pas le caractère '\340'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ echo -e "/* bonjour \0340 vous */" | sed '/\/\*.*/s/\(\/\*.*\)/\1XXX/g'
    /* bonjour XXX� vous */

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

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ od -c ytot
    0000000   /   *       b   o   n   j   o   u   r     340       v   o   u
    0000020   s       *   /  \n
    0000025
    $ LANG=C sed  's/'`echo -e "\0340"`'/à/' ytot
    /* bonjour à vous */
    $ LANG=C sed  's/'`echo -e "\0340"`'/à/' ytot | od -c
    0000000   /   *       b   o   n   j   o   u   r     303 240       v   o
    0000020   u   s       *   /  \n
    0000026

  6. #6
    Membre très actif
    Profil pro
    ingénieur
    Inscrit en
    Novembre 2011
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Novembre 2011
    Messages : 165
    Par défaut
    @zipe31: non ça n'est pas la finalité, c'était juste pour illustrer ^^

    @jack-ft: chez moi (redHat 5) la proposition de ivelios fonctionne, mais en effet un seul \340 est matché.

    @disedorgue: désolé, je ne pige pas ta proposition :/

  7. #7
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 429
    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 429
    Par défaut
    Je ne faisais que répondre sur le post de jack-ft

    Plus sérieusement, c'est quoi la finalité ou le problème que tu cherche à résoudre car c'est possible de le faire, mais il faut être conscient que tu vas avoir des fichiers avec des plusieurs charset dans le même fichier.

    Souvent, une simple redéfinition de ton locale suffit pour avoir un affichage correcte.

  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
    Citation Envoyé par tiresias54 Voir le message
    @zipe31: non ça n'est pas la finalité, c'était juste pour illustrer ^^
    Ok et c'est quoi la finalité alors ?

    Remplacer n'importe quoi dans une ligne de commentaire ?
    Remplacer que les codes du style "\340" par leur équivalence ?

    Désolé mais pour moi ton exemple n'est pas très parlant

  9. #9
    Membre très actif
    Profil pro
    ingénieur
    Inscrit en
    Novembre 2011
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Novembre 2011
    Messages : 165
    Par défaut
    Citation Envoyé par zipe31 Voir le message
    Ok et c'est quoi la finalité alors ?

    Remplacer n'importe quoi dans une ligne de commentaire ?
    Remplacer que les codes du style "\340" par leur équivalence ?

    Désolé mais pour moi ton exemple n'est pas très parlant
    J'ai "hérité" de fichiers dans lesquels éèàçù,etc... ont été remplacé par leur valeur octale.
    Mais pour que les commentaires soient lisibles, j'aimerais les remplacer par leur équivalent latin1.
    Je suis obligé de garder les valeurs octale dans le code.

    Donc il s'agit de remplacer les occurrences de \350, \351, \340, etc. par èéà, etc mais uniquement dans les lignes de commentaire.

    J’espère que c'est plus clair ^^

  10. #10
    Membre Expert Avatar de Ivelios
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    1 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 031
    Par défaut
    (Re)Bonjour

    Quelque chose dans le style ça devrait plus le faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed '\#^/\*.*\*/$# s#\\340#à#g' monFichier
    \#^/\*.*\*/$# -> Ligne de forme /* N'importe quoi */

  11. #11
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 429
    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 429
    Par défaut
    Ok, je comprends mieux, on est sur du faux code octal.

    Donc ton souci est plus sur la reconnaissance de ces chaines dans du commentaire C.
    Mais est que le commentaire est toujours symbolisé par "/*" et "*/" ou il peut y avoir la forme non standart "//" ?
    D'ailleurs, juste comme ça, un commentaire peut être sur plusieurs lignes quand on est en "/*" et "*/".
    Donc pour le sed, c'est plus compliqué que ce que j'ai pu voir, pour le moment, dans cette discussion ...

  12. #12
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 307
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [~/Documents]$ echo '/*bonjour \0340 vous*/ printf("bonjour \0340 vous");'
    /*bonjour \0340 vous*/ printf("bonjour \0340 vous");
    [~/Documents]$ echo '/*bonjour \0340 vous*/ printf("bonjour \0340 vous");'|sed 's@\(/\*[^\\]*\)\\0340@\1à@g'
    /*bonjour à vous*/ printf("bonjour \0340 vous");

  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
    Il te faut construire un fichier de commandes sed contenant tous les remplacements à effectués. Ici un exemple avec les lettres accentuées "à é è ê ë î ï ù ü ô ö"

    Le fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ cat plop 
      /* vous \340 vous */
    printf("bonjour \340 vous et \340 vos parents");
      /* O\371 # commentaire sur plusieurs lignes
      \352tes 
      vous */
    printf("O\371 \352tes vous ?");
      /* \364 vous */
    printf("\364 vous");
      /* vos \356les sous le vent */
    printf("vos \364 sous le vent");
    Le script sed :
    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
    $ cat script.sed
    \|^\s\+/\*|! b
     
    \|^\s\+/\*.*\*/$|{
    b z
    }
     
    \|^\s\+/\*|{
    :a
    N
    \|\*/$|! b a
    }
     
    :z
    {
    s|\\340|à|g
    s|\\351|é|g
    s|\\350|è|g
    s|\\352|ê|g
    s|\\353|ë|g
    s|\\356|î|g
    s|\\357|ï|g
    s|\\371|ù|g
    s|\\374|ü|g
    s|\\364|ô|g
    s|\\366|ö|g
    }
    L'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ sed -f script.sed plop 
      /* vous à vous */
    printf("bonjour \340 vous et \340 vos parents");
      /*# commentaire sur plusieurs lignes
      êtes 
      vous */
    printf("O\371 \352tes vous ?");
      /* ô vous */
    printf("\364 vous");
      /* vos îles sous le vent */
    printf("vos \364 sous le vent");

  14. #14
    Membre très actif
    Profil pro
    ingénieur
    Inscrit en
    Novembre 2011
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Novembre 2011
    Messages : 165
    Par défaut
    marche pas chez moi

    avec cette version:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ sed --version
    GNU sed version 4.1.5
    Copyright (C) 2003 Free Software Foundation, Inc.

  15. #15
    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
    Que te renvoie la commande suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ echo "/* vous \340 vous */" | sed 's|\\340|à|'
    Sinon pour la version chez moi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ sed --version
    GNU sed version 4.2.1

  16. #16
    Membre très actif
    Profil pro
    ingénieur
    Inscrit en
    Novembre 2011
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Novembre 2011
    Messages : 165
    Par défaut
    j'ai l'impression que c'est lorsque j'essaie de passer par le script que ça foire...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ echo "/* vous \340 vous */" | sed 's|\\340|à|'
    /* vous à vous */
    ceci dit les solutions de flodelarab et ivelios fonctionnent. De plus les commentaires dans le code sont sur une ligne et il n'y a pas de commentaire non standard. J'essayerai cependant ta solution chez moi pour voir si ça fonctionne, et surtout pour essayer de la comprendre ^^

  17. #17
    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 tiresias54 Voir le message
    j'ai l'impression que c'est lorsque j'essaie de passer par le script que ça foire...
    Affiche-le pour voir

    De plus les commentaires dans le code sont sur une ligne et il n'y a pas de commentaire non standard.
    A ce moment là, on peut réduire le script comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    \#^\s\+/\*#{
    s|\\340|à|g
    s|\\351|é|g
    s|\\350|è|g
    s|\\352|ê|g
    s|\\353|ë|g
    s|\\356|î|g
    s|\\357|ï|g
    s|\\371|ù|g
    s|\\374|ü|g
    s|\\364|ô|g
    s|\\366|ö|g
    }
    J'essayerai cependant ta solution chez moi pour voir si ça fonctionne, et surtout pour essayer de la comprendre ^^
    On cible un motif correspondant à un ligne qui commence par plusieurs espace (^\s\+) suivis par un slash lui même suivi par une astérisque (/\*).

    Si le motif est trouvé on applique les substitutions qui suivent en fonction des codes trouvés...

  18. #18
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 429
    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 429
    Par défaut
    Voici une méthode qui fonctionne chez moi (tout au moins sur l'exemple utilisé) car je suis sur le bon charset, c'est à dire que si je fais par exemple:
    cela m'affiche bien le à.
    Ma version sed accepte aussi la commande "e"
    Donc voici la solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ cat testtr.txt
      /* vous \340 vous */
    printf("bonjour \340 vous et \340 vos parents");
      /* O\371 # commentaire sur plusieurs lignes
      \352tes
      vous */
    printf("O\371 \352tes vous ?");
      /* \364 vous */
    printf("\364 vous");
      /* vos \356les sous le vent */
    printf("vos \364 sous le vent");
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ sed  '/\/\*.*\*\//btr;/\/\*/,/\*\//btr;b;:tr;s/\\\([1-9]\)/\\0\1/g;s/\(.*\)/echo -e "\1"/eg' testtr.txt
    Résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      /* vous à vous */
    printf("bonjour \340 vous et \340 vos parents");
      /*# commentaire sur plusieurs lignes
      êtes
      vous */
    printf("O\371 \352tes vous ?");
      /* ô vous */
    printf("\364 vous");
      /* vos îles sous le vent */
    printf("vos \364 sous le vent");

  19. #19
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    il faut être conscient que tu vas avoir des fichiers avec des plusieurs charset dans le même fichier.

    Souvent, une simple redéfinition de ton locale suffit pour avoir un affichage correcte.
    Je plussoie!!!

    En iso-8859-1 (latin-1), le 'e-acute' (é) est codé sur un byte \351
    En unicode (utf-8), le 'e-acute' (é) est codé sur 2 bytes \303 \251

    Avec 'od -c' ou 'cat -A', on peut voir le codage précis d'un fichier et donc déterminer le charset utilisé.

    Si on voit des \351 (ou un '?') à la place d'un 'é', c'est qu'on affiche de l'iso-8859-1 dans un environnement utf8 (ou en croyant que c'est de l'utf8).

    Si on voit des \303 \251 (ou des Ã(c)), c'est qu'on affiche de l'utf8 dans un environnement iso-8859-1 (ou en croyant que c'est de l'iso-8859-1).


    Dans ton cas, manifestement, le charset de ton fichier est iso-8859-1 (latin-1) et tu l'affiches dans un environnement utf-8.
    Donc, pour le voir correctement, tu peux faire (avec un uuoc):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat file | iconv -f ISO_8859-1 -t utf8
    Ou alors tu règles ton locale "correctement" (plus facile à dire qu'à faire!), et tout ton fichier va s'afficher "correctement" (les commentaires autant que les printf).

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

Discussions similaires

  1. Comment faire des remplacements dans des fichiers (sed + regex)
    Par vinok972 dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 04/12/2012, 12h50
  2. text dans des blocs
    Par Razorbak dans le forum Mise en page CSS
    Réponses: 6
    Dernier message: 12/01/2010, 10h10
  3. [XSL]<b> et </b> dans des blocs if différents ?
    Par Eylir dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 17/08/2009, 09h56
  4. Recherche dans des blocs maitre/détail
    Par imed0083 dans le forum Forms
    Réponses: 7
    Dernier message: 15/10/2008, 17h26
  5. programme qui plante. chercher/remplacer dans des fichiers.
    Par [Hugo] dans le forum Général Python
    Réponses: 2
    Dernier message: 31/10/2006, 17h10

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