在xargs变量上使用sed在shell扩展中不起作用

Exc*_*bur 4 bash sed redis

我试图在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)应该工作吧?(如果是这样,我该怎么做呢?)

Joh*_*024 7

单独使用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版本不进行替换?

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永远不会进行替换.

使xargs和shell按正确顺序协同工作

有一个解决方法:

$ 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不会处理该字符串.