单独使用 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”)。下一个替换放入“development”,然后该版本也会被打印。
Update:假设我们希望输出在一行上:
$ 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 才会处理该字符串。