Soluzione con sed da solo
sed stessa è in grado di produrre sia la riga non modificata che quella modificata:
$ echo "redis::staging::key" | sed 's/^/RENAME /; p; s/staging/development/g'
RENAME redis::staging::key
RENAME redis::development::key
In quanto sopra, sed prima aggiunge la stringa RENAME all'inizio della riga. Quindi, il p
comando dice a sed di stampare la riga così com'è in quel momento (con "staging" ancora in essa). La sostituzione successiva mette in "sviluppo" e poi viene stampata anche quella versione.
Aggiornamento: Supponiamo di volere l'output su una riga:
$ echo "redis::staging::key" | sed 's/.*/RENAME & &/; s/staging/development/2'
RENAME redis::staging::key redis::development::key
Le prime s
il comando sopra aggiunge RENAME all'inizio e quindi raddoppia la riga. Il secondo sostituisce la seconda occorrenza della messa in scena con lo sviluppo.
Perché la versione xargs non ha effettuato la sostituzione?
xargs -I {} echo "RENAME {} $(echo {} | sed 's/staging/development/g')"
Prima dell'esecuzione di xargs, bash elabora le stringhe. In particolare, vede $(echo {} | sed 's/staging/development/g')
e lo esegue ("sostituzione comando") e ottiene il risultato {}
. Quindi, quando xargs viene finalmente eseguito, vede il comando:
xargs -I {} echo "RENAME {} {}"
Di conseguenza, il s/staging/development/g
la sostituzione non viene mai effettuata.
Fai in modo che xargs e shell lavorino insieme nell'ordine corretto
C'è una soluzione per questo:
$ echo "redis::staging::key" | xargs -I {} sh -c 'echo RENAME {} $(echo {} | sed 's/staging/development/g')'
RENAME redis::staging::key redis::development::key
Quanto sopra mette i comandi bash tra virgolette singole e li passa come argomenti a sh
. In questo modo, la stringa non viene elaborata dalla shell fino a quando xargs non ha effettuato le sostituzioni.