我想拆分字符串,如'substring1 substring2 ONCE [0,10s] substring3'。预期的结果应该是(带有分隔符 'ONCE [0,10s]'):Bash脚本 - 使用正则表达式分隔符分割字符串
substring1 substring2
substring3
的问题是,在分隔符的数量是可变的,如 'ONCE [0,1s]' 或“ONCE [0 ,3m]'或'一次[0,10d]'等等。
如何在bash脚本中执行此操作?任何想法 ?
谢谢
我想拆分字符串,如'substring1 substring2 ONCE [0,10s] substring3'。预期的结果应该是(带有分隔符 'ONCE [0,10s]'):Bash脚本 - 使用正则表达式分隔符分割字符串
substring1 substring2
substring3
的问题是,在分隔符的数量是可变的,如 'ONCE [0,1s]' 或“ONCE [0 ,3m]'或'一次[0,10d]'等等。
如何在bash脚本中执行此操作?任何想法 ?
谢谢
你可以使用awk
。指定字段分隔为:
'ONCE[[]0,[^]]*[]] *'
例如,使用您的样本输入:
$ awk -F 'ONCE[[]0,[^]]*[]] *' '{for(i=1;i<=NF;i++){printf $i"\n"}}' <<< "substring1 substring2 ONCE[0,10s] substring3"
substring1 substring2
substring3
的bash:
s='substring1 substring2 ONCE[0,10s] substring3'
if [[ $s =~ (.+)" ONCE["[0-9]+,[0-9]+[smhd]"] "(.+) ]]; then
echo "${BASH_REMATCH[1]}"
echo "${BASH_REMATCH[2]}"
else
echo no match
fi
substring1 substring2
substring3
在OP提供的示例(如以及@GlennJackman和@devnull提供的两个答案)假设实际的问题本来可以的:
在bash中,如何用换行符替换字符串中正则表达式的匹配项。
这实际上与“使用正则表达式分割字符串”不同,除非您添加约束条件,即该字符串不包含任何换行符。即使如此,它实际上并没有“分裂”字符串。假定其他进程将使用换行符来分割结果。
一旦问题得到重新解决,解决方案并不具有挑战性。你可以使用支持正则表达式的任何工具,如sed
:
sed 's/ *ONCE\[[^]]*] */\n/g' <<<"$variable"
(删除g
,如果你只是想更换第一序列,你可能需要调整正则表达式,因为它不是很清除所需的约束条件是什么。)
bash
本身不提供replace all
原始的使用正则表达式,但它确实有“图案”,如果该选项extglob
设置(这是一些分布在默认),图案足以表达图案,因此您可以使用:
echo "${variable//*()ONCE\[*([^]])]*()/$'\n'}"
同样,你可以替换只能通过改变//
到/
发生一次,你可能需要改变模式,以满足您的具体需求。
这留下了一个问题,即如何使用正则表达式指定的分隔符实际分割bash变量,以便对“split”进行某些定义。一个可能的定义是“以字符串的部分作为参数来调用函数”;这就是我们在这里使用了一个:
# 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