Løsning med sed alene
sed, selv, er i stand til at producere både den umodificerede og den modificerede linje:
$ echo "redis::staging::key" | sed 's/^/RENAME /; p; s/staging/development/g'
RENAME redis::staging::key
RENAME redis::development::key
I ovenstående tilføjer sed først RENAME-strengen til begyndelsen af linjen. Derefter, p
kommandoen fortæller sed at udskrive linjen, som den står på det tidspunkt (med "staging" stadig i den). Den næste udskiftning sætter "udvikling" ind, og så udskrives den version også.
Opdatering: Antag, at vi vil have output på én linje:
$ echo "redis::staging::key" | sed 's/.*/RENAME & &/; s/staging/development/2'
RENAME redis::staging::key redis::development::key
De første s
kommandoen ovenfor tilføjer RENAME til begyndelsen og fordobler derefter linjen. Den anden erstatter den anden forekomst af iscenesættelse med udvikling.
Hvorfor foretog xargs-versionen ikke erstatningen?
xargs -I {} echo "RENAME {} $(echo {} | sed 's/staging/development/g')"
Før xargs udføres, behandler bash strengene. Især ser den $(echo {} | sed 's/staging/development/g')
og den udfører den ("kommandosubstitution") og får resultatet {}
. Så når xargs endelig køres, ser den kommandoen:
xargs -I {} echo "RENAME {} {}"
Følgelig er s/staging/development/g
substitution foretages aldrig.
At få xargs og shell til at arbejde sammen i den rigtige rækkefølge
Der er en rettelse til dette:
$ echo "redis::staging::key" | xargs -I {} sh -c 'echo RENAME {} $(echo {} | sed 's/staging/development/g')'
RENAME redis::staging::key redis::development::key
Ovenstående sætter bash-kommandoerne inden for enkelte anførselstegn og sender dem som argumenter til sh
. På denne måde behandles strengen ikke af skallen, før xargs har foretaget udskiftningerne.