Bash使用正则表达式替换变量中的字符串

时间:2019-11-19 19:56:04

标签: regex bash

我正在尝试使用正则表达式替换变量中的字符串。但是,一旦我使用正则表达式就无法正常工作。

源字符串:

数字可以是任何数字,可以是任何有效整数。

message='"autotermination_minutes": 15,'

期望的字符串

   message='"autotermination_minutes": 30,'

以下工作正常(没有正则表达式)

echo ${message/'"autotermination_minutes": 15'/'"autotermination_minutes": 30'}

以下操作不起作用(对于Regex)

echo ${message/'"autotermination_minutes": '[0-9]/'"autotermination_minutes": 30'}

它显示在输出

之后
"autotermination_minutes": 305,

3 个答案:

答案 0 :(得分:1)

[0-9]仅匹配一位数字。

使用[0-9][0-9]来匹配两个:

➜ echo ${message/'"autotermination_minutes": '[0-9][0-9]/'"autotermination_minutes": 30'}
"autotermination_minutes": 30,

请注意,Bash参数替换的功能非常有限。您在这里所做的甚至与正则表达式都没有关系,这些模式只是glob。因此,您需要使用[0-9]+来匹配一个或多个数字,而不是正则表达式期望的+([0-9])

➜ shopt -s extglob
➜ echo ${message/'"autotermination_minutes": '+([0-9])/'"autotermination_minutes": 30'}
"autotermination_minutes": 15,

另请参阅here

但是您确实应该使用sedperl

➜ echo "$message" | sed -E 's/[0-9]+/30/'
"autotermination_minutes": 30,

或者,如果您输入的是JSON,则您确实应该使用JSON解析器并正确读取/写入文件,而不是使用正则表达式。

答案 1 :(得分:1)

在纯bash中,无法从原始字符串中捕获值并使用反向引用将其替换回来。

您可以在此处使用带有捕获组和反向引用的简单sed

message='"autotermination_minutes": 15,'
sed -E 's/("autotermination_minutes": *)[0-9]+/\130/' <<< "$message"

"autotermination_minutes": 30,

答案 2 :(得分:0)

仅打击bash的解决方案:

message='"autotermination_minutes": 15,'
pattern='(.*autotermination_minutes":[[:blank:]]*)([[:digit:]]+)(.*)'
replacement='30'

if [[ $message =~ $pattern ]]; then
    echo "${BASH_REMATCH[1]}${replacement}${BASH_REMATCH[3]}"
else
    echo "$message"
fi

请注意,与适当设计的sedawk解决方案相比,它在代码大小和执行时间上均效率较低。