我试图在Redis中进行批量密钥重命名,使用shell为每个密钥名称替换一个替换.(似乎没有更好的方法在redis内部执行此操作).
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
Run Code Online (Sandbox Code Playgroud)
我期待这样的输出:
"RENAME redis::staging::key redis::development::key"
相反,我得到这个:
"RENAME redis::staging::key redis::staging::key"
该echo {} $(echo {}| sed 's/old/new/')是什么是挂了我...怎样才能正确地实现服用xargs输出和回声原始和那一个编辑的版本?$(echo {} |sed)应该工作吧?(如果是这样,我该怎么做呢?)
sed本身能够生成未修改和修改的行:
$ echo "redis::staging::key" | sed 's/^/RENAME /; p; s/staging/development/g'
RENAME redis::staging::key
RENAME redis::development::key
Run Code Online (Sandbox Code Playgroud)
在上面,sed首先将RENAME字符串添加到行的开头.然后,该p命令告诉sed打印当时的行("暂存"仍然在其中).下一个替换放入"开发",然后也打印该版本.
更新: 假设我们希望输出在一行:
$ echo "redis::staging::key" | sed 's/.*/RENAME & &/; s/staging/development/2'
RENAME redis::staging::key redis::development::key
Run Code Online (Sandbox Code Playgroud)
s上面的第一个命令将RENAME添加到开头,然后将该行加倍.第二个用开发替换第二次登台.
xargs -I {} echo "RENAME {} $(echo {} | sed 's/staging/development/g')"
Run Code Online (Sandbox Code Playgroud)
在xargs执行之前,bash处理字符串.特别是,它看到$(echo {} | sed 's/staging/development/g')并执行它("命令替换")并获得结果{}.因此,当最终运行xargs时,它会看到命令:
xargs -I {} echo "RENAME {} {}"
Run Code Online (Sandbox Code Playgroud)
因此,s/staging/development/g永远不会进行替换.
有一个解决方法:
$ echo "redis::staging::key" | xargs -I {} sh -c 'echo RENAME {} $(echo {} | sed 's/staging/development/g')'
RENAME redis::staging::key redis::development::key
Run Code Online (Sandbox Code Playgroud)
上面将bash命令放在单引号中并将它们作为参数传递给sh.这样,在xargs进行替换之前,shell不会处理该字符串.