我有这个示例字符串:
test_string="13A6"
此字符/数字可以是0到9以及从A到F.
我想要这个输出:
1 3 A 6
我有这个工作:
result=$(echo ${test_string} | sed 's/./& /g')
我想在没有sed的情况下这样做...我有另一个解决方案,我不太喜欢......很脏: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中引用匹配的char本身就是这种纯粹的bash语法。任何bash大师? :)
答案 0 :(得分:4)
这个怎么样(没有调用外部工具):
str="13A6"
[[ $str =~ ${str//?/(.)} ]]
printf '%s\n' "${BASH_REMATCH[*]:1}"
结果(没有尾随空格):
"1 3 A 6"
或者,如果您需要使用其他分隔符:
[[ $str =~ ${str//?/(.)} ]]
( IFS=$'\n'; printf "%s\n" "${BASH_REMATCH[*]:1}")
或者,在函数中,IFS可能是函数的本地函数:
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建议将数组中的@
更改为*
。这避免了使用时间数组或位置参数的需要。
答案 1 :(得分:0)
我不知道它是否像你想要的那样纯净:
test_string="13A6"
length=$( expr length "$test_string" )
s=""
for (( i=1;i<=${length};i++))
do
c=$( expr substr "${test_string}" $i 1 )
s=${s}" "$c
done
echo $s
Res:
1 3 A 6
或者在chepner的帮助下最纯粹(没有外部程序)。
test_string="13A6"
s=""
for ((i=0;i<${#test_string};i++))
do
s=${s}" "${test_string:i:1}
done
echo $s