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 le remplacement d'une chaîne de caractères


Sujet :

Shell et commandes GNU

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Autre
    Inscrit en
    Février 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Février 2015
    Messages : 8
    Points : 8
    Points
    8
    Par défaut Sed et le remplacement d'une chaîne de caractères
    Bonjour,

    Encore désolée de vous embêter avec mes problèmes de newbie mais voici le dernier.
    Dans un fichier, je veux isoler une chaîne de caractère a un emplacement prédéfini, et ensuite remplacer ce dernier par une autre chaîne prédéfinie elle aussi.
    Okay, je m'explique un peu mieux.
    Un exemple de fichier
    ABCD 1234 abc
    EFGH 5678 efg
    Pour simplifier en premier lieu, imaginons que je veuille isoler par exemple le 6ème caractère si sa valeur est égale 5 alors le remplacer par un X, sur l'intégralité du fichier. J'ai beau eu lire et tester des trucs différents, la fonction sed doit m'échapper. Est-ce que je peux l'utiliser dans ce cas précis? Car j'ignore comment noter ma variable à remplacer pour qu'elle soit interprétée comme elle se doit.

    Au départ j'avais imaginé quelque chose dans le genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    cat $fichier | while read line
    do
    var=$(echo $line | cut -c6)
    if [$var=5]
    then
    sed -e 's/$var/X/' $fichier #ici je n'ai volontairement pas variabiliser le X, une chose à la fois
    fi;done
    Mais le problème, ici je pense, c'est que ma valeur est interprétée comme une valeur définie et non à une place définie dans le fichier.
    Je tourne en rond, je ne trouve pas. J'ai tenté avec d'autres astuces lu dans le man, mais ça m'échappe. Le problème également de ce fichier, c'est que parfois quand il n'y a pas de data, c'est simplement remplacé par des blancs. Si je reprends mon exemple de fichier bidon, cela peut-être aussi ainsi:
    ABCD 1234 abc
            5678 efg
    Du coup, ça me parait délicat de déclarer que c'est la variable de tel bloc.
    Si quelqu'un pouvait m'aiguiller et tout au moins me dire si c'est possible ou non avec cette méthode en expliquant pourquoi, je serai ravie et toute ouïe.

  2. #2
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    avec sed je sais pas, mais en bash directement on peut faire quelque chose du genre :
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    while read line; do
       if [ "${line:5:1}" == "5" ]; then
          echo "${line::5}X${line:6}"  # on écrit les 5 premiers caractères, on écrit le X, on écrit le reste de la ligne
       else
          echo "$line" # sinon on affiche tel quel
       fi
    done < fichier

    ou avec awk aussi ca marche, sur le même principe :
    Code awk : Sélectionner tout - Visualiser dans une fenêtre à part
    awk 'substr($0,6,1) == "5" {print substr($0,1,5) "X" substr($0,7,length($0)); next} {print}' < fichier

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 246
    Points : 13 468
    Points
    13 468
    Par défaut
    Bonjour,

    lorsqu'une variable est entre simple quotes, il n'y a pas d'interprétation donc $var ne sera pas remplacé.
    Il suffit de sortir des quotes, comme ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ var=9
    $ cat /tmp/nop
    ABCD 1234 abc
    EFGH 5678 efg
    $ sed 's/\(^.....\)5/\1'"$var"'/' /tmp/nop
    ABCD 1234 abc
    EFGH 9678 efg
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  4. #4
    Futur Membre du Club
    Femme Profil pro
    Autre
    Inscrit en
    Février 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Février 2015
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Procédons par ordre:
    @ BufferBob
    => En effet, je n'avais pas pensé à rééditer tout le fichier de cette manière. Faut que je voies et j'adapte pour voir si ça colle ou pas
    => Pour le awk, pourrais tu, s'il te plait expliciter un poil ta ligne? (Je cherche en même temps de mon côté)

    @ Flodelarab
    =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed 's/\(^.....\)5/\1'"$var"'/' /tmp/nop
    Okay je pense comprendre la ligne. Cependant... étant donné que dans la réalité mes conditions se trouvent être en position 400 et des bananes, je ne suis pas sur de pouvoir l'appliquer ainsi...
    Et pourrais-tu me dire, si le fait de définir en variable la valeur d'une position est possible de la réutiliser dans sed? (Navrée si je ne suis pas claire.)

  5. #5
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par Niemand Voir le message
    => En effet, je n'avais pas pensé à rééditer tout le fichier de cette manière. Faut que je voies et j'adapte pour voir si ça colle ou pas
    il y aura de toutes façons pas d'autre alternative en vérité, les chaines de caractères n'étant pas directement modifiables en bash, on est obligé de créer une nouvelle chaine à partir de l'ancienne, rien n'empêche de l'affecter au même nom de variable cela dit line="${line::5}X${line:6}"
    Citation Envoyé par Niemand Voir le message
    => Pour le awk, pourrais tu, s'il te plait expliciter un poil ta ligne? (Je cherche en même temps de mon côté)
    la logique de awk est assez simple, et fonctionne en condition {instructions}, l'instruction next indique à l’interpréteur que le traitement de la ligne est terminé et il passe donc à la ligne suivante, quant à la fonction substr() elle permet de "prélever" un morceau de la chaine, ici $0 qui représente la ligne entière (cf les paramètres positionnels dans awk)

    en dépliant la ligne ça devient peut-être plus lisible (ou pas ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    substr($0,6,1) == "5" # ici la condition...
    {
       print substr($0,1,5) "X" substr($0,7,length($0)); # ...et son traitement; on construit (affiche) une nouvelle ligne
       next  # et on passe à la ligne suivante
    }
    { # on atterit dans ce bloc d'instruction seulement si le 'next' n'a pas été rencontré, et donc si la condition de départ n'a pas été vérifiée; c'est le 'else'
       print # on affiche la ligne telle quel
    }
    note que là encore on peut envisager quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    line=$(awk 'substr($0,6,1) == "5" {print substr($0,1,5) "X" substr($0,7,length($0)); next} {print}' <<< "$line")
    ah et on peut également variabiliser le "5" si besoin du genre :
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var=5
    line=$(awk -vTOTO="$var" 'substr($0,6,1) == TOTO {print substr($0,1,5) "X" substr($0,7,length($0)); next} {print}' <<< "$line")

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 246
    Points : 13 468
    Points
    13 468
    Par défaut
    Même question, même réponse: il suffit de sortir des quotes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ pos=5
    $ sed 's/\(^.\{'"$pos"'\}\)5/\1'"$var"'/' /tmp/nop
    ABCD 1234 abc
    EFGH 9678 efg
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

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

    Pour le fun, une solution via gnu awk:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    VAR=9
    awk -vVAR=$VAR -F '' '$6 == "5" ? $6=VAR : 1' OFS='' fichier
    Cordialement.

  8. #8
    Futur Membre du Club
    Femme Profil pro
    Autre
    Inscrit en
    Février 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Février 2015
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    @ BufferBob: Merci pour ces éclairages. Bon je suis en train d'éplucher la awk, ce n'est pas forcément ce qu'il y'a de plus trivial quand on fait connaissance avec cette fonction.

    @ Flodelarab: Okay. J'avais compris pour des variables prédéfinies, mais j'ignorais si cela s'appliquait également à ce type de variable, d'où la récurrence de ma question.

    @ disedorgue: Euh merci pour ce petit moment de "fun". Cependant, je vais rester sur une manière plus scolaire, histoire que je comprenne et je me souvienne de ce que j'ai fait, (ainsi que pour mon collègue).

    Je vais tenter de gribouiller mon script, et si j'ai une autre question je vous dérangerai à nouveau.

  9. #9
    Futur Membre du Club
    Femme Profil pro
    Autre
    Inscrit en
    Février 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Février 2015
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Des p'tites news...
    Hier sur ma bécanne, grâce à vos précieux conseils, j'ai réussi à bricoler des trucs qui semblaient marcher. Mais cette après-midi en passant sur sur le véritable environnement, tout plein d'erreurs ou de non retour. Après petite recherche via des codes erreurs, il s'avère simplement que cette machine est sous une version antérieure: bash88. D'où des incompatibilité de syntaxe. Et je pense le jour où les environnements seront isos, on aura découvert que la licorne n'est pas un mythe.
    Enfin bref, du coup faut que je rectifie le tir.

  10. #10
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 294
    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 294
    Points : 12 770
    Points
    12 770
    Par défaut
    Tu voulais dire ksh88 au lieu de bash88 ?

    Quel est le système d'exploitation de la machine finale (tu peux le voir via la commande "uname -a") ?
    Cordialement.

  11. #11
    Futur Membre du Club
    Femme Profil pro
    Autre
    Inscrit en
    Février 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Février 2015
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Désolée pour le temps de réponse, alors l'os: Unix Aix 5.3
    Cependant, je peux mettre le topic en résolu, j'ai bidouillé, ça fonctionne. Le seul regret que j'ai, ce n'est pas aussi propre que je l'aurai voulu. Mais la demande étant dite "urgente" (comme toujours), j'ai fait au plus simple. Quand j'aurai cinq minutes, je me pencherai à nouveau sur le sujet.
    Merci à vous tous

  12. #12
    Invité
    Invité(e)
    Par défaut
    C'est vrai qu'en mode console on ne vois pas trop de différence entre un Linux et un AIX (qui est un Unix).
    Par contre lorsqu'on essaye d'utiliser les commandes on a des surprises
    J'avais galéré pour trouver une solution correcte pour faire un simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -i "s/toto/tata/" fichier
    vu que mon fichier pouvait être modifié à tout moment
    L'option i n'existant pas sous AIX.

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

Discussions similaires

  1. Réponses: 11
    Dernier message: 15/07/2014, 09h52
  2. [MySQL] Remplacer une chaîne de caractères dans une base de données
    Par Furius dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 27/11/2013, 21h06
  3. Réponses: 0
    Dernier message: 19/01/2009, 10h00
  4. Réponses: 4
    Dernier message: 04/11/2006, 20h36
  5. Remplacer une chaîne de caractères dans une base
    Par Furius dans le forum Requêtes
    Réponses: 4
    Dernier message: 19/10/2005, 23h03

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