Forum Astuces.divers [Terminal] Changements rapides avec sed

Posté par  .
Étiquettes : aucune
0
6
juin
2001
Changer un terme apparaissant fréquemment dans un fichier texte en un autre, c'est très simple avec sed, il suffit de lancer la commande cat fichier | sed s/"mot_ancien"/"mot_nouveau"/g > fichier De meme il est simple de supprimer certains termes assez rapidement en lançant, cette fois, cat fichier | sed /"mot_a_virer"/d > fichier. Mieux, on peut se servir des expression regulières, par exemple, en lançant cat fichier | sed /^$/d > fichier pour supprimer dans le fichier les lignes blanches.
  • # le cat ne sert à rien

    Posté par  (site web personnel) . Évalué à 1.

    sed s/foo/bar/ fichier_origine > fichier_modifie D'une manière plus générale cat fichier | prog se remplace avantageusement (1 process de moins) par prog < fichier
    • [^] # Re: le cat ne sert à rien

      Posté par  . Évalué à 1.

      Ca permet de moins "forker" effectivement.

      Mais bon vu la pauvre charge que ça génère, cela est négligeable.

      dabowl_75

      • [^] # Re: le cat ne sert à rien

        Posté par  . Évalué à 1.

        Ca permet de moins "forker" effectivement.
        Pas seulement. Ca évite aussi la création d'un pipe.

        Par contre je pense qu'il est important de préciser que les fichiers source et destination doivent porter des noms différents si tu ne veux pas te retrouver avec un fichier de taille nulle.
        • [^] # Re: le cat ne sert à rien

          Posté par  . Évalué à 1.

          C'est vrai que ce dernier point est important et a été malencontreusement oublié.

          Pour le reste, je trouvais que le cat identifiait bien qui fait quoi et justement le fait que ça se tuyaute. Car finalement, ce genre d'utilisation de sed se fait souvent à la sortie d'autres commandes (donc plus subtiles que cat)
    • [^] # Re: le cat ne sert à rien

      Posté par  . Évalué à 1.

      oui, mais c'est un exemple qu'on peut utiliser pour faire derriere un ls ou un autre programme.

      ex:
      ls | sort
    • [^] # Re: le cat ne sert à rien

      Posté par  . Évalué à 1.

      Sauf que la syntaxe proposée, comme dit plus bas, permet de ne pas créer un autre fichier. Comme ce sont deux commandes disctinctes, tu peux, sans risque, écrire sur le fichier que tu lis !

      Enfin, une autre manière de faire tout de même, mais qui ne fonctionne que si le mot à remaplacer et au plus aussi long que le mot qui le remplace :

      sed "s/foo/bar/" 3<>fichier 0<&3>&3

      Donc, on ouvre "fichier" en lecteur/écriture avec le descripteur 3 et on redirige l'entrée et la sortie standard vers le fichier de descripteur 3.

      Le seul problème c'est que du coup le fichier n'est pas tronqué si le résultat est plus court. Par contre, si le résultat est plus long, ben apparemment ça marche (ça doit dépendre de comment sed marche ... donc il faut quand même faire attention !)
      • [^] # Re: le cat ne sert à rien

        Posté par  . Évalué à 1.

        > Sauf que la syntaxe proposée, comme dit plus bas, permet de ne pas créer un autre fichier. Comme ce sont deux commandes disctinctes, tu peux, sans risque, écrire sur le fichier que tu lis !

        Faux. le comportement de "cat toto | sed ... > toto' dépend du shell. Tu n'as aucune certitude que toto sera tout lu avant d'être réécrit.
        Tu supposes que le 'read()' de cat lit tout le lichier avant le 'open(O_CREATE, ...)' du shell. Je n'ai pas testé, mais je parie que c'est faux au moins pour les gros fichiers (qui ne tiennent pas en mémoire et sont lus bout par bout par cat).

        L'option '-i' ou '--in-place' de sed permet par contre de modifier un fichier sans le renommer/faire une copie/...
        • [^] # Re: le cat ne sert à rien

          Posté par  . Évalué à 1.

          Merveilleux le coup du -i (connaissais pas) !!!
          Avant j'y allais de ruses affreuses à grands coups de echo -e ",s/bidule/machin/ \n wq" | ed monfichier, efficace quand c'est en place mais tellement prise de tête à régler. Je crois que mes scripts vont prendre un coup de jeune, là :)
        • [^] # Re: le cat ne sert à rien

          Posté par  (site web personnel) . Évalué à 1.

          Tu la sors d'ou ton option -i ? Ca n'existe pas sur ma mandrake, avec un sed 3.02 .
        • [^] # Re: le cat ne sert à rien

          Posté par  (site web personnel) . Évalué à 1.

          Hmm, si c'est comme perl -i, y'a bien une copie temporaire qui est créé.
  • # Re: Changements rapides avec sed

    Posté par  . Évalué à 1.

    Il m'est arrivé d'utiser cela avec une autre syntaxe:
    sed s/toto/titi fichier > fichier
    Cela a pour simple effet de se retrouver fichier à 0 !!!

    Par contre, la solution proposée dans l'astuce fonctionne tres bien... ! Prudence donc !
  • # Re: Changements rapides avec sed

    Posté par  (site web personnel) . Évalué à 2.

    le mieux est de le faire avec perl, il n'y pas besoin de renommer le fichier:
    perl -pi -e 's/toto/titi/g' fichier1 fichier2 fichierX
  • # Re: Changements rapides avec sed

    Posté par  . Évalué à 1.

    L'ideal serait de le faire avec ed ed fichier << EOF 1,$s/"mot_ancien"/"mot_nouveau"/g w q EOF Le probléme, c'est que ca marche pas, car la sauvegarde est faite avant que tout les mots soit remplacé. Par contre, si on lance les commandes les unes apres les autres, cela marche.
    • [^] # Re: Changements rapides avec sed

      Posté par  . Évalué à 2.

      Pour compléter, la syntaxe suivante peut être utile pour la mise au point :

      ed -s fichier <<-ENDOFSED

      H
      1,$ g/mot_ancien/s//mot_nouveau/
      w
      q

      ENDOFSED

      Le H donne une sortie plus lisible en cas d'erreur et cette syntaxe (-ENDOFSED) autorise l'indentation du code avec des tabulations.
      En outre, cela a toujours marché quelque soit l'"UNIX" (AIX, Sun, DEC, HP/UX, ...)

      Pour finir, cette syntaxe est beaucoup moins consommatrice qu'un pipe ou que l'utilisation de descripteurs de fichiers signalés plus haut.
  • # ATTENTION avec /d

    Posté par  (site web personnel) . Évalué à 1.

    Salut,

    La commande cat fichier | sed /"mot_a_virer"/d > fichier ne va pas supprimer "mot_a_virer" mais toutes les LIGNES qui contiennent ce mot.

    Yann.
  • # On peut également utiliser des scripts

    Posté par  (site web personnel) . Évalué à 1.

    sed -f script ficher_entree >fichier_sortie

    Le script se présente comme une suite de commandes (une par ligne) :
    - # blablabla : commentaire
    - s/avant/apres/ : remplace UNE fois "avant" par "apres" (expressions régulières)
    - s/avant/apres/g : remplace toutes les occurences de "avant" par "apres" (expressions régulières)
    - ... (lire une bonne doc (man sed), y'a un bon paquet de fonctions!!!)

    Si vos expressions contiennent le caractère '/', il faut l'écrire '\/'. Ou plus simplement : "s@/usr/bin@/usr/sbin@g" => On peut utiliser n'importe quel caractère après le 's' pour délimiter les expressions.

    Syntaxe pour les expressions régulières UNIX -> Sed :
    .*?+ -> .*\?\+
    [...] -> [...]
    (...) -> \(...\)
    ^a$ -> ^a$
    Attention : le texte "truc[1].txt" s'écrit "truc\[1\]\.txt" !

    Exemple :
    --- script ---
    s@elefant\(s\)\?@éléphant\1@g
    --- txt ---
    J'ai croisé un elefant au supermarché avec ses pôtes elefants !
    --- sed -f script txt --
    J'ai croisé un éléphant au supermarché avec ses pôtes éléphants !
    ---
    Autres exemples : http://www.haypocalc.com/logiciel/regex_sed.php(...)

    Note: Attention, sous Windows les scripts doivent être sauvés dans le format UNIX sous peine de lire des "sed: file script line 1: Unknown option to 's' " !

    Haypo
  • # Juste en passant

    Posté par  . Évalué à 1.

    le caractere / n'est pas strict donc par exemple, s/avant/apres/ peut s'ecrire aussi syavantyapresy (c'est moins lisible, mais ca perment d'eviter les palanquées de s/\//\/\//g)
    • [^] # Re: Juste en passant

      Posté par  (site web personnel, Mastodon) . Évalué à 1.

      c'est pas strict, donc autant remplacer un truc à rallonge par un truc illisible...

      'fin bref, tout ca pour dire que l'on peut adapter aussi la lisibilité :
      ex : remplacer ja/b par b/aj

      s!ja/b!b/aj! voir même s^ja/b^b/aj^
      plutot que :
      syja/byb/ajy ou s/ja\/b/b\/aj/

      enfin bon après, les gouts et les couleurs...

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.