[英]Using sed on xargs variable isn't working inside shell expansion
I am attempting to do a batch key rename in Redis, using the shell to sed a replacement for each key name. 我试图在Redis中进行批量密钥重命名,使用shell为每个密钥名称替换一个替换。 (There doesn't seem to be a better way to do this in redis internally). (似乎没有更好的方法在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
I am expecting an output like this: "RENAME redis::staging::key redis::development::key"
我期待这样的输出: "RENAME redis::staging::key redis::development::key"
Instead I just get this: "RENAME redis::staging::key redis::staging::key"
相反,我得到这个: "RENAME redis::staging::key redis::staging::key"
The echo {} $(echo {}| sed 's/old/new/')
is what is hanging me up... How does one properly achieve taking an xargs
output and echo both the original and an edited version of that? echo {} $(echo {}| sed 's/old/new/')
让我感到高兴...如何正确地实现xargs
输出并回显原始版本和编辑版本? $(echo {} |sed)
should work, right? $(echo {} |sed)
应该有效,对吗? (If so, how can I do it correctly?) (如果是这样,我该怎么做呢?)
sed, itself, is able to produce both the unmodified and the modified line: sed本身能够生成未修改和修改的行:
$ echo "redis::staging::key" | sed 's/^/RENAME /; p; s/staging/development/g'
RENAME redis::staging::key
RENAME redis::development::key
In the above, sed first adds the RENAME string to the beginning of the line. 在上面,sed首先将RENAME字符串添加到行的开头。 Then, the p
command tells sed to print the line as it stands at that time (with "staging" still in it). 然后, p
命令告诉sed打印当时的行(“暂存”仍然在其中)。 The next substitution puts in "development" and then that version is printed also. 下一个替换放入“开发”,然后也打印该版本。
Update: Suppose we want the output on one line: 更新:假设我们希望输出在一行:
$ echo "redis::staging::key" | sed 's/.*/RENAME & &/; s/staging/development/2'
RENAME redis::staging::key redis::development::key
The first s
command above adds RENAME to the beginning and then doubles the line. 上面的第一个s
命令将RENAME添加到开头,然后将该行加倍。 The second replaces the second occurrence of staging with development. 第二个用开发替换第二次登台。
xargs -I {} echo "RENAME {} $(echo {} | sed 's/staging/development/g')"
Before xargs executes, bash processes the strings. 在xargs执行之前,bash处理字符串。 In particular, it sees $(echo {} | sed 's/staging/development/g')
and it executes it ("command substitution") and gets the result {}
. 特别是,它看到$(echo {} | sed 's/staging/development/g')
并执行它(“命令替换”)并得到结果{}
。 So, when xargs is finally run, it sees the command: 因此,当最终运行xargs时,它会看到命令:
xargs -I {} echo "RENAME {} {}"
Consequently, the s/staging/development/g
substitution is never made. 因此,永远不会进行s/staging/development/g
替换。
There is a fix for this: 有一个解决方法:
$ echo "redis::staging::key" | xargs -I {} sh -c 'echo RENAME {} $(echo {} | sed 's/staging/development/g')'
RENAME redis::staging::key redis::development::key
The above puts the bash commands within single-quotes and passes them as arguments to sh
. 上面将bash命令放在单引号中并将它们作为参数传递给sh
。 This way, the string is not processed by the shell until after xargs has made the substitutions. 这样,在xargs进行替换之前,shell不会处理该字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.