I am attempting to do a batch key rename in Redis, using the shell to sed a replacement for each key name. (There doesn't seem to be a better way to do this in redis internally).
redis-cli -n 5 KEYS "*::staging::*"| xargs -I {} echo "RENAME {} $(echo {} | sed 's/staging/development/g')"
# Then pipe this command into redis-cli when working
I am expecting an output like this:
"RENAME redis::staging::key redis::development::key"
Instead I just get this:
"RENAME redis::staging::key redis::staging::key"
The echo {} $(echo {}| sed 's/old/new/')
is what is hanging me up...
How does one properly achieve taking an xargs
output and echo both the original and an edited version of that? $(echo {} |sed)
should work, right? (If so, how can I do it correctly?)
sed, itself, is able to produce both the unmodified and the modified line:
$ echo "redis::staging::key" | sed 's/^/RENAME /; p; s/staging/development/g'
RENAME redis::staging::key
RENAME redis::development::key
In the above, sed first adds the RENAME string to the beginning of the line. Then, the p
command tells sed to print the line as it stands at that time (with "staging" still in it). The next substitution puts in "development" and then that version is printed also.
Update: Suppose we want the output on one line:
$ echo "redis::staging::key" | sed 's/.*/RENAME & &/; s/staging/development/2'
RENAME redis::staging::key redis::development::key
The first s
command above adds RENAME to the beginning and then doubles the line. The second replaces the second occurrence of staging with development.
xargs -I {} echo "RENAME {} $(echo {} | sed 's/staging/development/g')"
Before xargs executes, bash processes the strings. In particular, it sees $(echo {} | sed 's/staging/development/g')
and it executes it ("command substitution") and gets the result {}
. So, when xargs is finally run, it sees the command:
xargs -I {} echo "RENAME {} {}"
Consequently, the s/staging/development/g
substitution is never made.
There is a fix for this:
$ echo "redis::staging::key" | xargs -I {} sh -c 'echo RENAME {} $(echo {} | sed 's/staging/development/g')'
RENAME redis::staging::key redis::development::key
The above puts the bash commands within single-quotes and passes them as arguments to sh
. This way, the string is not processed by the shell until after xargs has made the substitutions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With