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.