Решение само със sed
sed сам по себе си е в състояние да произведе както немодифицирания, така и модифицирания ред:
$ echo "redis::staging::key" | sed 's/^/RENAME /; p; s/staging/development/g'
RENAME redis::staging::key
RENAME redis::development::key
В горното, sed първо добавя низа RENAME в началото на реда. След това p
командата казва на sed да отпечата реда, както е в това време (с "постановка" все още в него). Следващата замяна поставя "разработка" и след това тази версия също се отпечатва.
Актуализация: Да предположим, че искаме изхода на един ред:
$ echo "redis::staging::key" | sed 's/.*/RENAME & &/; s/staging/development/2'
RENAME redis::staging::key redis::development::key
Първият s
командата по-горе добавя RENAME към началото и след това удвоява реда. Втората заменя втората поява на стадия с развитие.
Защо версията на xargs не направи замяната?
xargs -I {} echo "RENAME {} $(echo {} | sed 's/staging/development/g')"
Преди да се изпълни xargs, bash обработва низовете. По-специално, той вижда $(echo {} | sed 's/staging/development/g')
и го изпълнява ("замяна на команда") и получава резултата {}
. Така че, когато xargs най-накрая се стартира, той вижда командата:
xargs -I {} echo "RENAME {} {}"
Следователно, s/staging/development/g
замяна никога не се прави.
Накарайте xargs и shell да работят заедно в правилен ред
Има решение за това:
$ echo "redis::staging::key" | xargs -I {} sh -c 'echo RENAME {} $(echo {} | sed 's/staging/development/g')'
RENAME redis::staging::key redis::development::key
Горното поставя командите bash в единични кавички и ги предава като аргументи на sh
. По този начин низът не се обработва от обвивката, докато xargs не направи заместванията.