iru*_*var 4 bash variable-substitution
这是一个有点人为的例子,但这里是:假设我有一个1.2.3.4
包含版本信息的变量,需要将.4
末尾的替换为.5
version=1.2.3.4
echo ${version%.*}.5
1.2.3.5 #no problem
Run Code Online (Sandbox Code Playgroud)
/
但是当我尝试用锚点“内联”替换%
时
echo ${version/%.*/.5}
1.5
Run Code Online (Sandbox Code Playgroud)
Bash 进行了贪心替换。有没有办法让 bash “非贪婪地”进行替换,以便我可以使用替换来替代早期的删除+追加方法?
我认为你不能non-greedy
in search and replace
,你只能通过子字符串删除来做到这一点。来自 bash 参考:
\n\n\n${参数/模式/字符串}
\n\n该模式被扩展以产生一个模式,就像文件名扩展一样。参数被扩展,并且pattern\n 与其值的最长匹配被替换为 string。如果模式以 \xe2\x80\x98/\xe2\x80\x99 开头,则模式的所有匹配项都将替换为字符串。通常仅替换\n 第一个匹配项。如果模式以 \xe2\x80\x98#\xe2\x80\x99 开头,则它必须在参数扩展值的开头匹配。如果模式以 \xe2\x80\x98%\xe2\x80\x99 开头,则它必须在参数扩展值的末尾匹配。\n 如果字符串为空,则删除模式的匹配项,并删除后面的 / n 模式可以省略。如果参数为 \xe2\x80\x98@\xe2\x80\x99 或 \xe2\x80\x98 \xe2\x80\x99,则依次对每个位置参数进行替换操作,扩展为结果列表。如果参数是数组变量\n,下标为 \xe2\x80\x98@\xe2\x80\x99 或 \xe2\x80\x98 \xe2\x80\x99 的数组变量,则替换操作将应用于\n 数组的每个成员反过来,扩展就是结果列表。
\n
要解决这个问题,您应该设置extglob
:
shopt -s extglob\nprintf \'%s\\n\' "${version/%.+([0-9])/.5}"\n1.2.3.5\n
Run Code Online (Sandbox Code Playgroud)\n\n或使用一些工具,例如sed
或perl
:
printf \'%s\\n\' "$version" | perl -pe \'s/\\.\\d+$/\\.5/\'\n1.2.3.5\n
Run Code Online (Sandbox Code Playgroud)\n