echo ddayaynightday | sed 's/day//g'
Sed sostituto ricorsivamente
Finisce daynight
Esiste un modo per farlo sostituire fino a quando non è più partita?
echo ddayaynightday | sed 's/day//g'
Sed sostituto ricorsivamente
Finisce daynight
Esiste un modo per farlo sostituire fino a quando non è più partita?
mio modulo preferito, per questo caso:
echo ddayaynightday | sed -e ':loop' -e 's/day//g' -e 't loop'
Questo è lo stesso di tutti gli altri, se non che utilizza i comandi -e più per rendere le tre linee e utilizza il costrutto t
, che significa "diramazione se si è eseguita correttamente la sostituzione", per eseguire l'iterazione.
Buono a sapersi inserire più righe di script sulla riga di comando nei casi in cui ";" non funzionerà Preferirei la tua risposta anche a causa del salto condizionale 't' che è più chiaro per me, al contrario di un pattern match con salto incondizionato. –
grazie :) penso che questo sembra buono, non sono sicuro se c'è un modo migliore di utilizzare alcuni regolari regolari ex .. – w00d
La bandiera g
deliberatamente non corrisponde nuovamente alla parte sostituita della stringa. Quello che devi fare è un po 'diverso. Prova questo:
echo ddayaynightday | sed $':begin\n/day/{ s///; bbegin\n}'
Grazie alla eccentricità di BSD Sed sono richiesti i ritorni a capo incorporati. Se stai usando GNU Sed si può essere in grado di cavarsela con
sed ':begin;/day/{ s///; bbegin }'
Nelle shell sh-like è anche possibile inserire una nuova riga letterale all'interno di una stringa quotata. D'altra parte trovo il '$ '... stringa con escapes ...'' costruisco più carino per script brevi come questo comunque. Per script veramente lunghi, usare '-f file' è probabilmente meglio. In questo caso particolare, funzionano anche molti comandi '-e'. – torek
@torek: buon punto sui molteplici comandi '-e'. Personalmente odio incorporare le newline in una stringa quotata. È in genere più difficile da leggere e rende molto più difficile condividere il comando con altre persone (poiché in genere i comandi dovrebbero trovarsi su un'unica riga). –
grazie, il tuo secondo non funziona sul mio osx, è sufficiente stampare l'input – w00d
le seguenti opere:
$ echo ddayaynightday | sed ':loop;/day/{s///g;b loop}'
night
A seconda del sistema, il ;
potrebbe non funzionare per separare i comandi, in modo da poter utilizzare il seguente invece:
echo ddayaynightday | sed -e ':loop' -e '/day/{s///g
b loop}'
Spiegazione:
:loop # Create the label 'loop'
/day/{ # if the pattern space matches 'day'
s///g # remove all occurrence of 'day' from the pattern space
b loop # go back to the label 'loop'
}
Se la porzione del comando b loop
non viene eseguita, i contenuti correnti dello spazio modello vengono stampati e viene letta la riga successiva.
con bash:
str=ddayaynightday
while true; do tmp=${str//day/}; [[ $tmp = $str ]] && break; str=$tmp; done
echo $str
Ripetere fino a quando la sua lunghezza non cambia più. Non so, come farlo nella shell. – kirilloid