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 et sa syntaxe


Sujet :

Shell et commandes GNU

  1. #1
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Points : 336
    Points
    336
    Par défaut sed et sa syntaxe
    Bonjour.

    J'essaie de remplacer un texte avec sed et le script suivant :
    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    chaines1=chaine1
    chaines2=chaine2
    sed -i -e "s/$chaines1/$chaines2/g" mon_fichier.txt

    et j'ai l'erreur :
    sed: -e expression #1, char 34: unknown option to `s'
    Je n'arrive pas à écrire correctement la séquence : "s/$chaines1/$chaines2/g"

    Merci de votre aide.

  2. #2
    Membre habitué
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Décembre 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Décembre 2013
    Messages : 70
    Points : 159
    Points
    159
    Par défaut
    Bonjour,

    Faudrait un exemple plus précis.
    Utiliser des variables dans sed, c'est sioux.
    Faut penser à protéger les caractères qui pourraient être interprétés par sed.

    Quelques exemples :
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    $ cat test.txt 
    tata
    titi
    toto
     
    $ ch1=a
    $ ch2=u
    $ sed "s/$ch1/$ch2/g" test.txt 
    tutu
    titi
    toto
     
    $ ch2='&'
    $ sed "s/$ch1/$ch2/g" test.txt 
    tata
    titi
    toto
     
    $ ch2='\&'
    $ sed "s/$ch1/$ch2/g" test.txt 
    t&t&
    titi
    toto
     
    $ ch2='&@'
    $ sed "s/$ch1/$ch2/g" test.txt 
    ta@ta@
    titi
    toto
     
    $ ch2='\&@'
    $ sed "s/$ch1/$ch2/g" test.txt 
    t&@t&@
    titi
    toto
     
    $ ch1='\('
    $ sed "s/$ch1/$ch2/g" test.txt 
    sed: -e expression n°1, caractère 10: Échec du pairage de ( ou de \(
    Edit :
    J'ai réussi à reproduire ton erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ ch2='/x'
    $ sed "s/$ch1/$ch2/g" test.txt 
    sed: -e expression n°1, caractère 6: option inconnue pour «*s*»
    Dans tes variables chaines1 et chaines2, il faut que tu mettes un antislash devant les slash (entres autres) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ ch2='\/x'
    $ sed "s/$ch1/$ch2/g" test.txt 
    t/xt/x
    titi
    toto

  3. #3
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed "s/${chaine1//\//\\/}/${chaine2//\//\\/}/g"
    Mais l'oblique est un faux problème. Tu auras des soucis à chaque fois que quelque chose est interprétable dans ta chaîne de caractère.
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  4. #4
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 276
    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 276
    Points : 12 721
    Points
    12 721
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ ord () 
    { 
        for ((i=0; i<${#1}; i++))
        do
            printf '\\x%x' "'${1:$i:1}";
        done
    }
    $ X1="X/;E"
    $ X2="Y,:F"
    $ X1=$(ord "$X1")
    $ X2=$(ord "$X2")
    $ echo "fooX/;Ebar" | sed -e "s/$X1/$X2/"
    fooY,:Fbar
    Bon là, c'est pour de la string pur, pas de regex, ou alors toute la partie regex, on ne la passe pas dans la moulinette de la fonction ord.
    Cordialement.

  5. #5
    Membre habitué
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Décembre 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Décembre 2013
    Messages : 70
    Points : 159
    Points
    159
    Par défaut
    C'est bien trouvé ça ! Moi je me serais embêté à mettre des antislash devant certains caractères.

  6. #6
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Désolé de jouer les rabat-joie, mais il faut toujours se souvenir que cette considération des caractères, octet par octet, se marie très mal avec les caractères unicode un peu poussé. Exemple : ☢

    ord () { for ((i=0; i<${#1}; i++)); do printf '\\x%x' "'${1:$i:1}"; done; }
    x1="X/;E"
    X1=$(ord "$x1")
    x2="☢Y,:F"
    X2=$(ord "$x2")
    echo "fooX/;Ebar" | sed -e "s/$X1/$X2/"

    donne

    foo&22Y,:Fbar

    Le code de ☢ est 2622.
    Or \x26 est l'esperluette.
    Vous voyez le problème.

    PS: la balise "code" défigure les caractères unicode.
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  7. #7
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Points : 336
    Points
    336
    Par défaut
    Merci beaucoup pour toutes vos remarques.

    j'ai identifié le problème, j'ai une chaîne de caractères de la forme "*/machaine" qui met le bazar dans mon sed.
    Cette chaîne, que je ne maîtrise pas en amont, est donnée en argument ($1) de mon script shell.

    Pour enlever ces 2 caractères que je ne maitrise pas mais qui sont toujours au début, j'ai essayé 2 choses :
    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    BRANCHE="*/lala"
    echo $BRANCHE | sed 's/\*\///'
    echo $BRANCHE
    BRANCHE=${BRANCHE:2}
    echo $BRANCHE

    Les 2 fonctionnent, par contre pour remplacer le contenu de la variable $BRANCHE, je n'y arrive pas, je ne trouve pas de moyen de supprimer la séquence "*/" ou les 2 premiers caractères de ce paramètre $1

  8. #8
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 276
    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 276
    Points : 12 721
    Points
    12 721
    Par défaut
    Citation Envoyé par Flodelarab Voir le message
    Désolé de jouer les rabat-joie, mais il faut toujours se souvenir que cette considération des caractères, octet par octet, se marie très mal avec les caractères unicode un peu poussé. Exemple : ☢

    ord () { for ((i=0; i<${#1}; i++)); do printf '\\x%x' "'${1:$i:1}"; done; }
    x1="X/;E"
    X1=$(ord "$x1")
    x2="☢Y,:F"
    X2=$(ord "$x2")
    echo "fooX/;Ebar" | sed -e "s/$X1/$X2/"

    donne

    foo&22Y,:Fbar

    Le code de ☢ est 2622.
    Or \x26 est l'esperluette.
    Vous voyez le problème.

    PS: la balise "code" défigure les caractères unicode.
    C'est printf qui transcode mal l'unicode, par exemple avec la version ci-dessous de ord, ça fonctionne chez moi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ord () { printf "$1" | hexdump -e '/1 "%02x"' | sed 's/../\\x&/g;' ;}

    @69Pierre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ echo $1
    */lala
    $ echo ${1:2}
    lala
    $ BRANCHE="${1:2}"
    $ echo "${BRANCHE}"
    lala
    Cordialement.

  9. #9
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    D'abord, bravo.

    Ensuite, j'avais déjà essayé de faire sortir des caractères unicode de sed avec la forme \x.., mais sans succès.
    J'ai réalisé aujourd'hui que je confondais le code unicode et son encodage en hexadécimal.
    Comme un âne, je tapais un truc du genre "sed 's/./\x26\x22/' <<< a". Alors que la bonne syntaxe est :
    $ sed 's/./\xe2\x98\xa2/' <<< a


    Je ne comprends encore pas trop pourquoi printf sort le code unicode 2622 au lieu de la représentation hexadécimale e298a2.

    @69Pierre : pour éviter d'échapper les obliques dans sed, utilise un autre séparateur dans la substitution.

    echo $BRANCHE | sed 's/\*\///'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo "$BRANCHE" | sed 's@\*/@@'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo "$BRANCHE" | sed 's|\*/||'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo "$BRANCHE" | sed 's,\*/,,'
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  10. #10
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Points : 336
    Points
    336
    Par défaut
    Ah oui, super, ça me donne le resultat escompté, mais comment mettre ce résultat dans une nouvelle variable ?

  11. #11
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Points : 336
    Points
    336
    Par défaut
    Citation Envoyé par 69Pierre Voir le message
    Ah oui, super, ça me donne le resultat escompté, mais comment mettre ce résultat dans une nouvelle variable ?
    Avec un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nouvelle_variable=`echo "$nom" | sed 's@\*/@_@'`
    , ça a l'ai bon

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Hum. Les `backticks` sont toujours dépassés, dépréciés, obsolètes, à mettre au rebut, au profit de $( ).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nouvelle_variable=$(echo "$nom" | sed 's@\*/@_@')
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  13. #13
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 276
    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 276
    Points : 12 721
    Points
    12 721
    Par défaut
    Citation Envoyé par Flodelarab Voir le message
    Je ne comprends encore pas trop pourquoi printf sort le code unicode 2622 au lieu de la représentation hexadécimale e298a2.
    En fait, printf transcode en unicode mais dans la norme \u2622 (ou \u61 pour le "a" qui est son code hexa) :
    donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ echo -e  "\u61 \x62"
    a b
    Par contre sed ne reconnait pas la forme '\u....'
    Cordialement.

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

Discussions similaires

  1. [Shell][sed]utilisation d'un sed pour gérer des doubles quotes
    Par bstevy dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 06/03/2015, 11h03
  2. Shell : sed, substitute et parenthèse capturante
    Par supertotal dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 04/05/2009, 12h22
  3. shell : sed et anti-côtes
    Par zg2pro dans le forum Linux
    Réponses: 3
    Dernier message: 01/04/2008, 22h54
  4. Suppression d'une ligne en shell ' sed' ou 'head'
    Par Findly dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 04/01/2008, 14h12
  5. Syntaxe dans un script shell
    Par cubepiege dans le forum Linux
    Réponses: 5
    Dernier message: 27/09/2005, 16h21

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