Lösning med enbart sed
sed, i sig själv, kan producera både den omodifierade och den modifierade raden:
$ echo "redis::staging::key" | sed 's/^/RENAME /; p; s/staging/development/g'
RENAME redis::staging::key
RENAME redis::development::key
I ovanstående lägger sed först till RENAME-strängen i början av raden. Sedan, p
kommandot säger åt sed att skriva ut raden som den står vid den tiden (med "staging" fortfarande i den). Nästa ersättning lägger in "utveckling" och sedan skrivs även den versionen ut.
Uppdatering: Anta att vi vill ha utdata på en rad:
$ echo "redis::staging::key" | sed 's/.*/RENAME & &/; s/staging/development/2'
RENAME redis::staging::key redis::development::key
De första s
kommandot ovan lägger till RENAME i början och dubblar sedan raden. Den andra ersätter den andra förekomsten av iscensättning med utveckling.
Varför gjorde inte xargs-versionen ersättningen?
xargs -I {} echo "RENAME {} $(echo {} | sed 's/staging/development/g')"
Innan xargs körs, bearbetar bash strängarna. I synnerhet ser den $(echo {} | sed 's/staging/development/g')
och den kör den ("kommandosubstitution") och får resultatet {}
. Så när xargs äntligen körs, ser den kommandot:
xargs -I {} echo "RENAME {} {}"
Följaktligen används s/staging/development/g
ersättning görs aldrig.
Få xargs och skal att fungera tillsammans i rätt ordning
Det finns en fix för detta:
$ echo "redis::staging::key" | xargs -I {} sh -c 'echo RENAME {} $(echo {} | sed 's/staging/development/g')'
RENAME redis::staging::key redis::development::key
Ovanstående sätter bash-kommandona inom enkla citattecken och skickar dem som argument till sh
. På så sätt bearbetas inte strängen av skalet förrän efter att xargs har gjort ersättningarna.