Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

Usar sed na variável xargs não está funcionando dentro da expansão do shell

Solução apenas com sed


O sed, por si só, é capaz de produzir tanto a linha não modificada quanto a modificada:
$ echo "redis::staging::key" | sed 's/^/RENAME /; p; s/staging/development/g'
RENAME redis::staging::key
RENAME redis::development::key

No exemplo acima, o sed primeiro adiciona a string RENAME ao início da linha. Então, o p O comando diz ao sed para imprimir a linha como está naquele momento (com "staging" ainda nela). A próxima substituição coloca em "desenvolvimento" e então essa versão é impressa também.

Atualização: Suponha que queremos a saída em uma linha:
$ echo "redis::staging::key" | sed 's/.*/RENAME & &/; s/staging/development/2'
RENAME redis::staging::key redis::development::key

Os primeiros s O comando acima adiciona RENAME ao início e dobra a linha. A segunda substitui a segunda ocorrência de encenação com desenvolvimento.

Por que a versão xargs não fez a substituição?

xargs -I {} echo "RENAME {} $(echo {} | sed 's/staging/development/g')"

Antes de xargs ser executado, o bash processa as strings. Em particular, ele vê $(echo {} | sed 's/staging/development/g') e o executa ("substituição de comando") e obtém o resultado {} . Então, quando o xargs finalmente é executado, ele vê o comando:
xargs -I {} echo "RENAME {} {}"

Consequentemente, o s/staging/development/g substituição nunca é feita.

Fazendo xargs e shell funcionarem juntos na ordem correta


Existe uma correção para isso:
$ echo "redis::staging::key" | xargs -I {} sh -c 'echo RENAME {} $(echo {} | sed 's/staging/development/g')'
RENAME redis::staging::key redis::development::key

O acima coloca os comandos bash entre aspas simples e os passa como argumentos para sh . Dessa forma, a string não é processada pelo shell até que xargs tenha feito as substituições.