我有以下案例:
正则表达式:$'\[OK\][[:space:]]+([[:alnum:]_]+)\.([[:alnum:]_]+)([^[]*)'
正文:
[OK] AAA.BBBBBB
aaabbbcccdddfffed
asdadadadadadsada
[OK] CCC.KKKKKKK
some text here
[OK] OKO.II
如果我使用这个网站https://regex101.com/r/qw4B5O/1将看起来像这样:
现在...如果我有下面的代码:
var_test=()
while [[ $text =~ $regex ]]; do
var_test+=("${BASH_REMATCH[@]:1}")
text=${text#*"${BASH_REMATCH[0]}"}
done
declare -p var_test
我将得到正确的输出:
declare -a var_test=([0]="AAA" [1]="BBBBBB" [2]=$'\naaabbbcccdddfffed\nasdadadadadadsada\n' [3]="CCC" [4]="KKKKKKK" [5]=$'\nsome text here\n' [6]="OKO" [7]="II" [8]="")
但是一旦我将它转换成这样一个函数:
function split_by_regex {
regex=$1
text=$2
groups=()
while [[ $text =~ $regex ]]; do
groups+=("${BASH_REMATCH[@]:1}")
text=${text#*"${BASH_REMATCH[0]}"}
done
echo "${groups[@]}"
}
res=($(split_by_regex "$regex" "$text"))
declare -p res
我将得到错误的输出:
declare -a res=([0]="AAA" [1]="BBBBBB" [2]="aaabbbcccdddfffed" [3]="asdadadadadadsada" [4]="CCC" [5]="KKKKKKK" [6]="some" [7]="text" [8]="here" [9]="OKO" [10]="II")
经过一些调试后,错误看起来像是来自echo "${groups[@]}"
,因为如果我在函数中检查groups
,它看起来应该是这样,但在我从函数中获得结果后,它不是。
抱歉,如果这是一个显而易见的问题,但我是新的bash和shell脚本,我正在努力弄清楚。
3条答案
按热度按时间fcg9iug31#
从函数中返回数组是很棘手的,因为正如您所注意到的,空格将被用于拆分数组中的值,因此不会被保留。
我建议使用
nameref
代替。uyhoqukh2#
由于性能原因,传输数组(使用nameref或global)是最有效的方法。如果这不起作用,可以使用readarray将子命令的(标准)输出解析为array。
对于输出不包含新行的简单情况,可以使用“printf”将数组转换为新行分隔的输出
对于一般情况,当输出可能包含新行时,可以使用NUL作为分隔符(类似于许多GNU实用程序支持的-print 0或-0),然后用NUL作为分隔符解析输出。如果NUL不起作用,可以使用
\1
。此外,无法使用单行文档(
<<<
)。在使用带有自定义分隔符的<<<
时,似乎是bash中的一个错误-它在文本中添加了一个新行,导致额外的注解。huus2vyu3#
另一种方法是在函数外部声明数组,如果工作流/要求允许的话,如下所示:
nameref
,上面的代码是一种替代方法。