我正在尝试使用正则表达式替换变量中的字符串。但是,一旦我使用正则表达式就无法正常工作。
源字符串:
数字可以是任何数字,可以是任何有效整数。
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,
答案 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。
但是您确实应该使用sed
或perl
:
➜ 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
请注意,与适当设计的sed
或awk
解决方案相比,它在代码大小和执行时间上均效率较低。