Il mio sospetto è che non puoi farlo nello standard sed
, ma potresti farlo con Perl o qualcos'altro con una gestione delle espressioni regolari più potente.
$ echo "She sells sea shells by the sea shore" |
> perl -pe 's/(sh[a-z]*)/"." x length($1)/gei'
... sells sea ...... by the sea .....
$
Il e
modificatore significa che il modello di sostituzione è uno script Perl eseguibile; in questo caso ripete il carattere .
tante volte quanti sono i caratteri nel modello corrispondente. Il g
il modificatore si ripete lungo la linea; il i
modificatore è per la corrispondenza senza distinzione tra maiuscole e minuscole. Il -p
L'opzione Perl stampa ogni riga dopo l'elaborazione nello script specificato dal -e
option — il comando sostitutivo.
questo awk-oneliner fa il lavoro per te?
awk '{for(i=1;i<=NF;i++)if($i~/^[Ss]h/)gsub(/./,".",$i)}1' file
prova con i tuoi dati:
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 .....
Una vecchia domanda, ma ho trovato una bella e relativamente breve soluzione sed di una riga:
sed ':a;s/\([Ss]h\.*\)[^\. ]/\1./;ta;s/[Ss]h/../g'
Funziona sostituendo un carattere alla volta in un ciclo.
:a;
avviare un ciclo
s/\([Ss]h\.*\)[^\. ]
cerca un sh
seguito da un qualsiasi numero di .
s (il nostro lavoro completato finora) seguito da un carattere diverso dal punto o dallo spazio (quello che andremo a sostituire)
/\1./;
sostituiscilo con il nostro lavoro completato finora più un altro .
.
ta;
se abbiamo fatto qualche sostituzione, loop, altrimenti...
s/[Ss]h/../g
sostituire il sh
s con due .
s e chiamalo un giorno.