Řešení se samotným sed
sed je sám o sobě schopen produkovat neupravenou i upravenou řadu:
$ echo "redis::staging::key" | sed 's/^/RENAME /; p; s/staging/development/g'
RENAME redis::staging::key
RENAME redis::development::key
Ve výše uvedeném sed nejprve přidá řetězec RENAME na začátek řádku. Poté p
příkaz sdělí sed, aby vytiskl řádek tak, jak stojí v daném okamžiku (se stále v něm "staging"). Další substituce vloží "vývoj" a pak se tato verze také vytiskne.
Aktualizace: Předpokládejme, že chceme výstup na jednom řádku:
$ echo "redis::staging::key" | sed 's/.*/RENAME & &/; s/staging/development/2'
RENAME redis::staging::key redis::development::key
První s
výše uvedený příkaz přidá RENAME na začátek a poté zdvojnásobí řádek. Druhý nahrazuje druhý výskyt stagingu s vývojem.
Proč verze xargs neprovedla náhradu?
xargs -I {} echo "RENAME {} $(echo {} | sed 's/staging/development/g')"
Před spuštěním xargs bash zpracuje řetězce. Konkrétně vidí $(echo {} | sed 's/staging/development/g')
a provede jej ("náhrada příkazu") a získá výsledek {}
. Takže když je xargs konečně spuštěn, uvidí příkaz:
xargs -I {} echo "RENAME {} {}"
V důsledku toho s/staging/development/g
substituce se nikdy neprovádí.
Jak vytvořit xargs a shell ve správném pořadí
Existuje oprava:
$ echo "redis::staging::key" | xargs -I {} sh -c 'echo RENAME {} $(echo {} | sed 's/staging/development/g')'
RENAME redis::staging::key redis::development::key
Výše uvedené vkládá příkazy bash do jednoduchých uvozovek a předává je jako argumenty sh
. Tímto způsobem není řetězec zpracován shellem, dokud xargs neprovede substituce.