Manipulation avec SED

Résolu
tht123 Messages postés 72 Statut Membre -  
tht123 Messages postés 72 Statut Membre -
Bonjour,

Voici mon fichier de départ "test01.txt"

lundi le la les
lundi le la les
lundi le la les
lundi le la les

suite à la commande :

>sed '2,3s/le/LES/g' test01.txt j'obtiens :

lundi le la les
lundi LES la LES s
lundi LES la LES s
lundi le la les

Mon problème est double:

1) Comment limiter le remplacement à 1 seule occurence par ligne, est-ce possible?

2)Ici j'utilise un adressage par ligne pour la commande substitute, mais est il possible d'adresser dans une ligne ??

Du style qui modifierait test01.txt comme suit :

lundi le la les
lundi LES la les
lundi LES la les
lundi le la les

D'avance merci, bonne après-midi.
Configuration: Windows XP
Internet Explorer 6.0

15 réponses

  1. Jean-François Pillou Messages postés 18961 Date d'inscription   Statut Webmaster Dernière intervention   63 308
     
    1) Enlève le 'g', qui est un attribut 'global' pour toute la ligne :
    sed '2,3s/le/LES/' test01.txt


    2) A priori avec la regexp ci-dessus ça donne le résultat escompté !
    0
  2. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    sed '2,3s/le/LES/1' test01.txt
    0
  3. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     
    1) Pour limiter le remplacement à une occurence, enlève le g à la fin du sed
    2) Il suffit de lire ton fichier ligne par ligne
    comment lire un fichier ligne par ligne

    Bonne chance
    0
  4. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898
     
    Salut,

    Voir aussi : sed substitution

    ;-))
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. tht123 Messages postés 72 Statut Membre
     
    1) Merci pour la solution d'une occurence par ligne!!!

    2) Concernant l'adressage dans une ligne (ex: remplacer ou effacer les caractères 15 et 16 de chaque ligne) cela semble bien fonctionner sous linux.

    Mais en fait il m'est imposé d'utiliser sed sous windows et donc je ne possède pas de possibilité de programmer des boucles.

    Sans possibilité de programmer des boucles, serais-je devant une impasse?

    Dores et déjà merci beaucoup.
    0
  7. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     
    Tu peux toujours lancer ta commande dans une commande shell (en séparant chaque ligne du script shell par des ';'). Exemple:
    cd plop ; ls
    0
  8. tht123 Messages postés 72 Statut Membre
     
    Excuse moi, mais Je ne te comprends pas.

    BAT
    0
  9. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     
    En faisant un truc du genre
    while read i; do echo -e "$i"; done < <(cat plop.txt)

    ... tu peux écrire une boucle en une commande shell...
    0
  10. tht123 Messages postés 72 Statut Membre
     
    Bonjour j'ai une alternative mais cela coince ,

    Pour le fichier de départ "test01.txt"

    lundi le la les
    lundi le la les
    lundi le la le
    lundi le la les

    sed '2,3s/le/LES/2' test01.txt

    La commande donne :

    lundi le la les
    lundi le la LESs
    lundi le la LES
    lundi le la les

    Là où cela coince, c'est que SED remplace même le "le" de "les"...
    ???

    BAT
    0
    1. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898
       
      Là où cela coince, c'est que SED remplace même le "le" de "les"...
      Ben c'est normal tu le lui demandes implicitement avec le "2" en fin de commande !
      sed '2,3s/le/LES/' test01.txt 
      ;-)
      0
  11. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     
    Pour ne catcher que les "le" suivi d'un ' ' :
    sed '2,3s/le /LES/2' plop.txt

    après je ne sais pas si ça fait ce que tu veux...
    0
    1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
       
      Salut,

      ça ne marche pas, puisque tu obliges d'avoir un espace après le et ce n'est pas toujours le cas
      lami20j@debian:~/trash$ cat test01.txt
      lundi le la les
      lundi le la les
      lundi le la le
      lundi le la les
      lami20j@debian:~/trash$ sed '2,3s/le /LES/2' test01.txt
      lundi le la les
      lundi le la les
      lundi le la le
      lundi le la les


      0
      1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944 > lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention  
         
        Exact
        0
  12. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    Là où cela coince, c'est que SED remplace même le "le" de "les"...
    Ben, ça ne coince pas.
    En réalité le moteur des regex n'est pas très intelligent. En revanche il est très persévérant et exhaustif. Donc ce qui coince c'est plutôt la manière dont on écrit et utilise une regex

    Dans ton cas le moteur s'en fiche complètement de ce que tu veux obtenir. Lui il cherche un le et il le remplace comme tu l'as demandé. Et comme tu n'as pas fait des demandes particulières, le moteur cherche la 2ème occurrence de le dans les lignes 2 à 3 n'importe s'il fait ou non partie d'un mot.

    Il faut spécifier au moteur que tu cherche à remplacer un
    caractère non mot suit d'un l suit d'un e suit d'un autre caractère non mot
    ou plutôt
    une assertion nulle début de mot suit d'un l suit d'un e suit d'une assertion  nulle fin de mot
    Donc il faut ancrer ton motif.
    Essaie comme ça
    lami20j@debian:~/trash$ cat test01.txt
    lundi le la les
    lundi le la les
    lundi le la le
    lundi le la les
    lami20j@debian:~/trash$ sed '2,3s/\ble\b/LES/2' test01.txt
    lundi le la les
    lundi le la les
    lundi le la LES
    lundi le la les
    lami20j@debian:~/trash$ sed '2,3s/\<le\>/LES/2' test01.txt
    lundi le la les
    lundi le la les
    lundi le la LES
    lundi le la les
    
    0
  13. Jean-François Pillou Messages postés 18961 Date d'inscription   Statut Webmaster Dernière intervention   63 308
     
    Si vous ne souhaitez pas qu'il capture 'le' s'il fait partie d'un mot :

    sed '2,3s/\ble\b/LES/' test01.txt


    \b représente une limite de mot !
    0
  14. tht123 Messages postés 72 Statut Membre
     
    Merci Jeff, et à tous les autres!!

    SED est vraiment puissant une fois que l'on connait les commandes et syntaxes mais malheureusement mal docummenté à priori

    Enfin, votre aide m'a beaucoup aidé

    A bientôt!
    0
  15. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    SED est vraiment puissant une fois que l'on connait les commandes et syntaxes

    En effet, SED et très puissant.
    Cependant ici il ne s'agit pas de SED mais des expressions régulières (regex).
    Les regex ne sont pas implémentées de la même façon dans toutes les langages (awk, perl, python, java, php, etc.) et dans toutes les commandes (sed, grep etc.) qui les utilisent donc avant de les utiliser il faut consulter la doc.
    En conclusion il faut les étudier avant de les utiliser pour éviter les résultats inattendues.

    Il y a plein des choses à apprendre en ce qui concerne les regex. Voici une petite liste :
    - les métacaractères
    - les classes de caractères
    - la gurmandise et la paresse des quantificateurs
    - les quantificateurs possessifs
    - la capture et les parenthèses non-capturantes
    - les références arrières
    - le groupement atomique
    - les assertions de largeur nulle ( les ancrages ) et non-nulle
    - les alternatives
    - les test avant et arrières (positives ou négatives)
    - les modificateurs de regex
    etc.

    En fait les regex c'est un mini langage qui a ses métacarctères qu'il faut les connaître.
    C'est aussi très important de connaitre la mécanique des regex ( les moteurs NFA et DFA)

    Tous ces langages partagent un même moteur, de type NFA (Nondeterministic Finite Automation). MySQL, awk et egrep, par contre, utilisent un autre type de moteur (DFA - Deterministic Finite Automation) plus simple, moins puissant mais plus rapide pour les cas (très) simples, voir simplistes ("Talking about DFA matching is very boring!" Jeffrey Friedl).


    En bref, les regex sont très puissantes.
    Quand vous aurez appris les expressions régulières, vous vous rendrez compte qu'elles constituent une partie inestimable de votre boîte à outils... by Jeffrey E.F. Friedl - Maîtrise des expressions régulières
    --
    lami20j
    0
  16. tht123 Messages postés 72 Statut Membre
     
    Merci encore à tous pour cet aflux impressionant de réponses!!!
    0