纯Bash替换捕获组 [英] Pure Bash replacement capturing groups
问题描述
我有这个示例字符串:
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屋!