我正在尝试在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
我期待这样的输出:
"RENAME redis::staging::key redis::development::key"
相反,我得到这个:
"RENAME redis::staging::key redis::staging::key"
echo {} $(echo {}| sed 's/old/new/')
让我感到很不舒服......
如何正确地实现xargs
输出并回显原始版本和编辑版本? $(echo {} |sed)
应该有效,对吧? (如果是这样,我该怎么做呢?)
答案 0 :(得分:7)
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 -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
替换。
有一个解决方法:
$ 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进行替换之前,shell不会处理该字符串。