纯Bash替换捕获组 [英] Pure Bash replacement capturing groups

查看:40
本文介绍了纯Bash替换捕获组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个示例字符串:

test_string="13A6"

此字符/数字可以从0到9,从A到F.

This chars/digits can be from 0 to 9 and from A to F.

我想要这个输出:

1 3 A 6

我正在工作:

result=$(echo ${test_string} | sed 's/./& /g')

我想在不使用sed的情况下做这件事...还有另一种我不太喜欢的解决方案...很脏:S

I want to do it without sed... and I have another solution which I don't like too much... is dirty :S

[[ ${test_string} =~ ^([0-9A-F])([0-9A-F])([0-9A-F])([0-9A-F]) ]] && result="${BASH_REMATCH[1]} ${BASH_REMATCH[2]} ${BASH_REMATCH[3]} ${BASH_REMATCH[4]}"

如果可能的话,我想使用语法 result = $ {variable//pattern/replacement} 的纯bash,但不确定如何做&"sed在这种纯bash语法上引用了匹配的char本身.任何bash大师?:)

I want, if possible, to use pure bash with the syntax result=${variable//pattern/replacement} but not sure how to do like "&" in sed to reference the matched char itself on this kind of pure bash syntax. Any bash guru? :)

推荐答案

如何解决(未调用任何外部实用程序):

How about this (no external utility called):

str="13A6"
[[ $str =~ ${str//?/(.)} ]]
printf '%s\n' "${BASH_REMATCH[*]:1}"

结果(无尾随空格):

"1 3 A 6"

或者,如果您需要使用其他分隔符:

Or, if you need to use a different separator:

[[ $str =~ ${str//?/(.)} ]]
( IFS=$'\n'; printf "%s\n" "${BASH_REMATCH[*]:1}")

或者,在一个函数中,IFS可能位于该函数的本地:

Or, in a function, IFS may be local to the function:

divide(){ 
    [[ $1 =~ ${1//?/(.)} ]]
    local IFS=${2:-' '}
    printf '%s\n' "${BASH_REMATCH[*]:1}"
}

divide "13A6" "-"            # will output 1-3-A-6 in this example.

这是这样的:

           ${str//?/(.)}              # Replace each character with "(.)".  
[[ $str =~               ]]           # Match the regex "(.)(.)(.) … …"  
                                      # capturing each character matched  
                                      # in the array "${BASH_REMATCH[@]}"  

printf '%s\n' "${BASH_REMATCH[*]:1}"  # Forget array index 0 and
                                      # convert the array to one string 
                                      # using the first character
                                      # of "$IFS" as separator
                                      # (no trailing separator). 

感谢@chepner建议将数组中的 @ 更改为 * .这避免了使用时间数组或位置参数的需要.

Thanks to @chepner for the recommendation to change a @ to a * in the array. That avoids the need to use a temporal array or the positional parameters.

这篇关于纯Bash替换捕获组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆