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.