OP 中提供的示例(以及@GlennJackman 和@devnull 提供的两个答案)假设实际问题可能是:
在 bash 中,如何用换行符替换字符串中正则表达式的匹配项。
这实际上与“使用正则表达式拆分字符串”不同,除非您添加字符串不包含任何换行符的约束。即便如此,它实际上并没有“拆分”字符串。假设其他进程将使用换行符来拆分结果。
一旦重新提出问题,解决方案就不再具有挑战性。你可以使用任何支持正则表达式的工具,例如sed:
sed 's/ *ONCE\[[^]]*] */\n/g' <<<"$variable"
(如果您只想替换第一个序列,请删除g;您可能需要调整正则表达式,因为不太清楚所需的约束是什么。)
bash 本身不提供使用正则表达式的replace all 原语,尽管它确实具有“模式”,并且如果设置了选项extglob(这是某些发行版的默认设置),模式就足够了强大的表达模式,所以你可以使用:
echo "${variable//*( )ONCE\[*([^]])]*( )/$'\n'}"
同样,您可以通过将 // 更改为 / 来使替换只发生一次,您可能需要更改模式以满足您的精确需求。
这留下了一个问题,即如何使用正则表达式指定的分隔符实际拆分 bash 变量,以获取“拆分”的某些定义。一种可能的定义是“以字符串的部分作为参数调用函数”;这就是我们在这里使用的:
# Usage:
# call_with_split <pattern> <string> <cmd> <args>...
# Splits string according to regular expression pattern and then invokes
# cmd args string-pieces
call_with_split () {
if [[ $2 =~ ($1).* ]]; then
call_with_split "$1" \
"${2:$((${#2} - ${#BASH_REMATCH[0]} + ${#BASH_REMATCH[1]}))}" \
"${@:3}" \
"${2:0:$((${#2} - ${#BASH_REMATCH[0]}))}"
else
"${@:3}" "$2"
fi
}
例子:
$ var="substring1 substring2 ONCE[0,10s] substring3"
$ call_with_split " ONCE\[[^]]*] " "$var" printf "%s\n"
substring1 substring2
substring3