sql >> Base de Datos >  >> NoSQL >> Redis

Usar sed en la variable xargs no funciona dentro de la expansión de shell

Solución con sed solo

sed, en sí mismo, es capaz de producir tanto la línea no modificada como la modificada:

$ echo "redis::staging::key" | sed 's/^/RENAME /; p; s/staging/development/g'
RENAME redis::staging::key
RENAME redis::development::key

En lo anterior, sed primero agrega la cadena RENAME al comienzo de la línea. Entonces, el p El comando le dice a sed que imprima la línea tal como está en ese momento (con "puesta en escena" todavía en ella). La siguiente sustitución pone "desarrollo" y luego esa versión también se imprime.

Actualización: Supongamos que queremos la salida en una línea:

$ echo "redis::staging::key" | sed 's/.*/RENAME & &/; s/staging/development/2'
RENAME redis::staging::key redis::development::key

Los primeros s El comando anterior agrega RENAME al principio y luego duplica la línea. El segundo reemplaza la segunda instancia de puesta en escena con desarrollo.

¿Por qué la versión xargs no hizo la sustitución?

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

Antes de que se ejecute xargs, bash procesa las cadenas. En particular, ve $(echo {} | sed 's/staging/development/g') y lo ejecuta ("sustitución de comando") y obtiene el resultado {} . Entonces, cuando finalmente se ejecuta xargs, ve el comando:

xargs -I {} echo "RENAME {} {}"

En consecuencia, el s/staging/development/g la sustitución nunca se realiza.

Hacer que xargs y shell funcionen juntos en el orden correcto

Hay una solución para esto:

$ echo "redis::staging::key" | xargs -I {} sh -c 'echo RENAME {} $(echo {} | sed 's/staging/development/g')'
RENAME redis::staging::key redis::development::key

Lo anterior pone los comandos bash entre comillas simples y los pasa como argumentos a sh . De esta forma, la cadena no es procesada por el shell hasta que xargs haya realizado las sustituciones.