Sylvain Sauvage, jeudi 20 décembre 2007, 16:04:19 CET >[…] > La commande « s » prend une ou deux « adresses » : > adr1,adr2 s/…/…/… > Ces adresses indiquent à s le cadre dans lequel il doit > opérer. Ce sont deux expressions régulières marquant la zone > de texte (une seule adresse → toute la ligne, deux adresses > → début et fin de zone).
Bon, je raconte n’importe quoi ! Pour sed, les adresses ne fonctionnent que sur plusieurs lignes. >[…] En revanche, la négation : > /\([^Dd]...\|[dD]\([^a]..\|a\([^t].\|t[^e]\)\)\)\[/,/\]/y/ /_/ > > en clair, on teste les quatre caractères avant le crochet : > — soit ce n’est pas d (ou D) ; > — soit c’est d (ou D) et, > — pas suivi d’un a ; > — suivi d’un a et, > — pas suivi d’un t ; > — suivi d’un t mais pas d’un e. > > (Merci tous les \ à mettre devant les () et les |… > Encore heureux que « xxx|yyy » n’a pas besoin d’être écrit > « (xxx)|(yyy) »…) > > Bon, là ça ne teste que [Dd]ate, tu pourras facilement > généraliser. … peut toujours servir. Mais ça devient très lourd à gérer avec sed. Il vaudrait vraiment passer à un vrai langage (Ruby, Perl…). Pour me pardonner d’avoir dit une ânerie : #!/usr/bin/ruby while ligne = STDIN.gets crochet = false until ligne.nil? case ligne when /\A[dD]ate\[/ print $& when /\A\[/ crochet = true print $& when /\A\]/ crochet = false print $& when /\A / if crochet print '_' else print ' ' end when /\A./ print $& end ligne = $' end print "\n" end (on peut faire plus court mais j’ai fait lisible…) Le principe est de manger la ligne petit bout par petit bout (le \A indique « début de la chaîne »). $& contient la correspondance de la regexp $' contient le reste de la chaîne -- Sylvain Sauvage