substitute text with equal length using sed

My suspicion is that you can't do it in standard sed, but you could do it with Perl or something else with more powerful regex handling.

$ echo "She sells sea shells by the sea shore" |
> perl -pe 's/(sh[a-z]*)/"." x length($1)/gei'
... sells sea ...... by the sea .....
$

The e modifier means that the replacement pattern is executable Perl script; in this case, it repeats the character . as many times as there are characters in the matched pattern. The g modifier repeats across the line; the i modifier is for case-insensitive matching. The -p option to Perl prints each line after the processing in the script specified by the -e option — the substitute command.


does this awk-oneliner do the job for you?

awk '{for(i=1;i<=NF;i++)if($i~/^[Ss]h/)gsub(/./,".",$i)}1' file

test with your data:

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 .....

An old question, but I found a nice and reletively short one line sed solution:

sed ':a;s/\([Ss]h\.*\)[^\. ]/\1./;ta;s/[Ss]h/../g'

Works by replacing one character at a time in a loop.

:a; start a loop

s/\([Ss]h\.*\)[^\. ] search for an sh followed by any number of .s (our completed work so far) followed by a non dot or space character (what we're going to replace)

/\1./; replace it by our completed work so far plus another ..

ta; if we made any substitution, loop, otherwise...

s/[Ss]h/../g replace the shs with two .s and call it a day.