Kecurigaan saya adalah Anda tidak dapat melakukannya dalam sed standar , tetapi Anda dapat melakukannya dengan Perl atau yang lainnya dengan penanganan regex yang lebih canggih.
$ echo "She sells sea shells by the sea shore" |
> perl -pe 's/(sh[a-z]*)/"." x length($1)/gei'
... sells sea ...... by the sea .....
$
e pengubah berarti bahwa pola pengganti adalah skrip Perl yang dapat dieksekusi; dalam hal ini, mengulangi karakter . sebanyak karakter dalam pola yang cocok. g pengubah berulang melintasi garis; i pengubah adalah untuk pencocokan case-insensitive. -p opsi untuk Perl mencetak setiap baris setelah pemrosesan dalam skrip yang ditentukan oleh -e opsi — perintah pengganti.
apakah awk-oneliner ini berhasil untuk Anda?
awk '{for(i=1;i<=NF;i++)if($i~/^[Ss]h/)gsub(/./,".",$i)}1' file
uji dengan data Anda:
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 .....
Sebuah pertanyaan lama, tetapi saya menemukan solusi sed satu baris yang bagus dan relatif pendek:
sed ':a;s/\([Ss]h\.*\)[^\. ]/\1./;ta;s/[Ss]h/../g'
Bekerja dengan mengganti satu karakter pada satu waktu dalam satu lingkaran.
:a; memulai putaran
s/\([Ss]h\.*\)[^\. ] cari sh diikuti dengan sejumlah . s (pekerjaan kita yang telah selesai sejauh ini) diikuti oleh karakter bukan titik atau spasi (apa yang akan kita ganti)
/\1./; ganti dengan pekerjaan kita yang telah selesai sejauh ini ditambah . lainnya .
ta; jika kami membuat substitusi, loop, jika tidak...
s/[Ss]h/../g ganti sh s dengan dua . s dan menyebutnya sehari.