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



我正试图在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)应该起作用,对吧?(如果是这样,我该如何正确操作?)

单独使用sed的解决方案

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按当时的状态打印行(其中仍包含"staging")。下一个替换是"开发",然后该版本也被打印出来。

更新:假设我们想要一行的输出:

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

上面的第一个s命令将RENAME添加到开头,然后将行加倍。第二个阶段用开发来代替第二次出现的阶段。

为什么xargs版本没有进行替换

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替换。

使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

上面将bash命令放在单引号中,并将它们作为参数传递给sh。这样,直到xargs进行了替换之后,shell才处理字符串。

相关内容

  • 没有找到相关文章