Je soupçonne que vous ne pouvez pas le faire dans la norme sed , mais vous pouvez le faire avec Perl ou autre chose avec une gestion plus puissante des regex.
$ echo "She sells sea shells by the sea shore" |
> perl -pe 's/(sh[a-z]*)/"." x length($1)/gei'
... sells sea ...... by the sea .....
$
Le e modificateur signifie que le modèle de remplacement est un script Perl exécutable ; dans ce cas, il répète le caractère . autant de fois qu'il y a de caractères dans le motif correspondant. Le g le modificateur se répète sur toute la ligne ; le i modificateur est pour la correspondance insensible à la casse. Le -p option à Perl imprime chaque ligne après le traitement dans le script spécifié par le -e option — la commande de remplacement.
est-ce que cet awk-oneliner fait le travail pour vous ?
awk '{for(i=1;i<=NF;i++)if($i~/^[Ss]h/)gsub(/./,".",$i)}1' file
tester avec vos données :
kent$ echo "She sells sea shells by the sea shore"|awk '{for(i=1;i<=NF;i++)if($i~/^[Ss]h/)gsub(/./,".",$i)}1'
... sells sea ...... by the sea .....
Une vieille question, mais j'ai trouvé une solution sed agréable et relativement courte :
sed ':a;s/\([Ss]h\.*\)[^\. ]/\1./;ta;s/[Ss]h/../g'
Fonctionne en remplaçant un caractère à la fois dans une boucle.
:a; démarrer une boucle
s/\([Ss]h\.*\)[^\. ] rechercher un sh suivi d'un nombre quelconque de . s (notre travail terminé jusqu'à présent) suivi d'un caractère autre qu'un point ou un espace (ce que nous allons remplacer)
/\1./; remplacez-le par notre travail terminé jusqu'à présent plus un autre . .
ta; si nous avons fait une substitution, une boucle, sinon...
s/[Ss]h/../g remplacer le sh s avec deux . s et appelez-le un jour.