Table des matières

mémo sed

Pas mal de scripts sur http://sed.sourceforge.net/grabbag/scripts/ (dont iso2html.sed)

Cette page existe en plus complet sur http://cli.asyd.net/home/filtres/sed

Une autre doc assez complète sur http://okki666.free.fr/docmaster/articles/linux130.html

Dans le “ Guide avancé d'écriture des scripts Bash”, la page sur les regex http://abs.traduc.org/abs-4.2.01-fr/ch17.html#regexref et celle sur sed http://abs.traduc.org/abs-4.2.01-fr/apc.html

Sans oublier le bon “Langages de scipts sous linux” de Christophe Blaess chez Eyrolles.

expression est en général de la forme

Commandes

sed -e '/pattern/a\
ajout d'une ligne\
et d'une autre.\
La dernière à ajouter n'ayant pas d'antislash
s/bla/bla/; # autre commande' < fichier_src > fichier_dest
sed -e '/^{/,/^}/c\
[... corps de la fonction ...]' < fichier.c > resume

rechercher/remplacer

s/search/replace/opt où opt peut être

Caractères particulier pour le remplacement :

Holdspace

Il est aussi possible d'utiliser le “holdspace” (un buffer secondaire).

Exemples

Effacer les lignes qui suivent un pattern, mais pas celle du pattern

sed -e '/pattern/,$ {
  # on affiche la 1re
  p
  # on efface les suivantes
  :boucle
    d
  $! b boucle
  # $! est la négation de $, qui signifie la dernière ligne
}'

Mais pour arriver au même résultat, cela paraît plus intelligent d'imprimer toutes les lignes jusqu'au pattern inclus (et pas les suivantes).

sed -ne '1,/pattern/ p'

Pour tout charger dans le buffer (pour du remplacement multilignes ensuite, à ne pas faire sur des fichiers de plus de qq ko)

{
  :boucle
    N
  $! b boucle
}

Récupérer les tailles d'images dans un mxml

#!/bin/sed -nf
# script de parsing des mxml pour récupérer les png et leur taille
# la taille peut être sur la ligne du Embed, mais pas toujours, et dans ce cas
# elle est précisée par la balise précédente qui précise une taille
 
# on cherche hauteur largeur
/width=/ {
  # faut garder la ligne entière pour la suite (au cas où il y aurait aussi du embed dedans) => on mémorise en holdspace
  h
  # on remplace width par height car on ne connait pas l'ordre (on aura height en double, on se fout de l'ordre)
  # si on voulait distinguer width et height, il faudrait deux blocs comme celui-ci
  s#width=#height=#
  s#.*height="\([0-9]*\)".*height="\([0-9]*\)".*#\1 \2#
  # on passe ces deux nb en holdspace et on récupère la ligne initiale
  x
}
 
# on cherche une image
/Embed('\/ressources\/medias\/images\// {
  s#.*@Embed('/ressources/medias/images\/\([^']*\)'.*#\1#;
  # on recupere le holdspace et les valeurs qui s'y trouvent sur une ligne sup
  G;
  # on vire le retour chariot qui s'y trouve
  s#\n# #
  # et on affiche
  p
}

Virer les commentaires

sed est “greedy” (gourmand, il prend la plus longue chaîne qui correspond) et y'a pas moyen de mettre *? pour le rendre “ungreedy”, faut donc ruser…

sed -e '{ :boucle; N; $! b boucle;}; s#/\*[^\*]*\*/##g' < fichier

Ça marche pour virer les “/* bla bla */” mais ça garde du “/* bla * bla */”, on peut peaufiner en virant d'abord les * (on les remplaçe par une chaîne exotique dont on suppose qu'elle n'existe pas au préalable, on traite et on remet)

sed -e '{ :boucle; N; $! b boucle;}; s/\([^/]\)\*\([^/]\)/\1µ£µ£µ£\2/g; s#/\*[^\*]*\*/##g; s/µ£µ£µ£/\*/g' < fichier

Et si on veut aussi virer les commentaires qui suivent “#” et “//”, et les lignes vides, alors, on ajoute :

#!/bin/sed -f    
 
# on charge tout dans le buffer
{ :boucle; N; $! b boucle;};
 
# on remplace les * isolés, vire les commentaires /* */ et on remets nos * isolés
s@\([^/]\)\*\([^/]\)@\1µ£µ£µ£\2@g;
s@/\*[^\*]*\*/@@g;
s@µ£µ£µ£@\*@g;
 
# On vire ce qui suit # sur une ligne
s@#[^\n]*@@g;
# les lignes qui commencent par ; (esp avant éventuels)
s@\n[ \t]*;[^\n]*@\n@g;
# et par //
s@\n[ \t]*//[^\n]*@\n@g;
# les espaces et tabulations seules sur leur ligne
s@\n[ \t]*\n@\n@g;
# et \n multiples qui pourraient rester après la commande précédente
s@[\n]\+@\n@g;

et dans un fichier d'alias ça donne (dans la définition de l'alias faut ajouter un \ devant $, \n et \t)

alias catsc='sed -e "{ :boucle; N; \$! b boucle;};
s@\([^/]\)\*\([^/]\)@\1µ£µ£µ£\2@g;
s@/\*[^\*]*\*/@@g;
s@µ£µ£µ£@\*@g;
s@#[^\\n]*@@g;
s@\\n[ \\t]*;[^\\n]*@\\n@g;
s@\\n[ \\t]*//[^\\n]*@\\n@g;
s@\\n[ \\t]*\\n@\\n@g;
s@[\\n]\+@\\n@g;"'

Récupérer des initiales

On utilise l'expression '\<' qui désigne le début d'un mot dans les expressions étendues ('\>' désigne la fin d'un mot). Attention, c'est juste un délimiteur (pas de caractère dedans). On entend par “mot” un changement alphanumérique/non-alpha. (script utilisé dans claws-mail, cf http://ll.lairdutemps.org/linux/claws-mail#personnalisation_et_scripts)

sed -re '
# vire ce qui suit un < s'il est précédé d'au moins une lettre
s/([a-zA-Z]+[^<]*)<.*/\1/;
# vire ce qui suit @
s/(.*)@.*/\1/;
#  met en capitale la première lettre d'un mot et vire les caractères non tiret-espace-point qui suivent, pour chaque occurence rencontrée
s/(\<.)[^- .]*/\U\1/g;
# vire les caractères tiret-espace-point
s/[- \."<]//g;
# ajoute "> " à la fin de ce qui reste
s/.*/&> /;'