为什么 sed 在我的替换中添加 0?

为什么 sed 在我的替换中添加 0?

我想用值“5.6.10”替换该变量

VERSION=5.4.38

如果我知道当前值,我知道该怎么做 (5.4.38)

sed s:VERSION=5.4.38:VERSION=5.6.10:g

但我想用 5.6.10 的内容替换,即使我不知道该值(对许多文件或脚本有用)。我试过这个

sed s:VERSION=[0-9].[0-9].[0-90-9]:VERSION=5.6.10:g

但结果很奇怪

VERSION=5.6.100

为什么10变成了100?

我也尝试过

sed s:VERSION=[0-9].[0-9].[0-9]:VERSION=5.6.10:g

我看到同样的结果。

答案1

[0-90-9]匹配一个字符,可以是任何数字。您的意思是[0-9][0-9]精确匹配两个数字。在这两次尝试中, 的最后一位数字5.6.100均未与正则表达式匹配,因此它在输出中存在且未更改。

另一个潜在的问题是.正则表达式中的特殊字符:它匹配任何字符。例如[0-9].[0-9].[0-9][0-9]匹配123.451a2b34.用于\.匹配点:特殊字符前的反斜杠使其变得非特殊。

此外,版本号可以具有更多或更少的数字。用于[0-9.]*匹配任意数量的点或数字。 (.当它位于括号内时不是特殊字符。) 更准确地说,[0-9.]*匹配尽可能长的点和数字序列,因此它将匹配所有这些字符。[0-9][0-9.]*如果您想强制开头至少有一个数字,请使用此选项。

sed 's:VERSION=[0-9][0-9.]*:VERSION=5.6.10:g'

答案2

假设您正确引用了表达式sed,以便 shell 不会将其扩展为文件名通配模式,则您的命令

sed 's:VERSION=[0-9].[0-9].[0-90-9]:VERSION=5.6.10:g'

会将字符串变成VERSION=5.4.38( VERSION=5.6.108not VERSION=5.6.100)。它这样做是因为[0-90-9]匹配单身的特点。因此,它被替换VERSION=5.4.3VERSION=5.6.10,而保留尾随8

替换中的其他奇怪之处sed包括不转义点(这些点将匹配任何单个字符),以及/g在最后使用,即使据我所知,您不希望与任何单行匹配多个字符串。

要替换表单上的模式VERSION=xx.yy.zz,其中xx等可以是任何数字字符串,请使用

sed 's/\(VERSION=\)[[:digit:]]\{1,\}\.[[:digit:]]\{1,\}\.[[:digit:]]\{1,\}/\15.6.10/'

或者,如果您想使用[0-9]而不是[[:digit:]]

sed 's/\(VERSION=\)[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}/\15.6.10/'

或者,如果您想使用扩展而不是基本正则表达式,

sed -E 's/(VERSION=)[0-9]+\.[0-9]+\.[0-9]+/\15.6.10/'

或者,如果你想进一步压缩它,

sed -E 's/(VERSION=)([0-9]+\.){2}[0-9]+/\15.6.10/'

或者,确实,

sed 's/\(VERSION=\).*/\15.6.10/'

...如果您需要的只是删除VERSION=字符串中的所有内容。

答案3

找到解决方案,添加一个点。这项工作适用于 5.5.10、6.4.20、3.2.20 等

sed s:VERSION=[0-9].[0-9].[0-9].:VERSION=5.6.10:g 

但不适用于 1.2.3 4.5.1 3.2.9 对于这对,这条线工作正常

sed s:VERSION=[0-9].[0-9].*.:VERSION=5.6.10:g 

相关内容