Bash for循环不等判断语法报错,如何修正以识别摩尔斯码分隔符?
解决Bash循环中的字符串比较语法错误与数组下标问题
我来帮你搞定这个问题!你的核心问题出在算术上下文里做字符串比较,还有字符串切片的用法搞错了,导致数组下标错误。咱们一步步来修正:
1. 为什么原来的代码会报错?
(( ... ))是Bash的算术运算上下文,只能用来处理数值计算和比较,不能直接做字符串对比。你在里面写${1:j:3} != " ",Bash会试图把这两个字符串当成数值解析,自然就抛出"operand expected"的语法错误;同时因为循环条件一直没正确触发,导致无限循环,最终数组下标也跟着出错。
2. 修正后的循环写法
咱们把for循环换成更合适的while循环,用[[ ... ]](Bash条件表达式)来做字符串比较,同时修正字符串切片的逻辑:
# 初始化j为当前起始位置i j=$i # 用[[ ]]做字符串比较,判断当前位置开始的3个字符是不是三个空格 while [[ "${1:j:3}" != " " ]]; do sleep 0.1 ((j++)) # 加个边界保护:防止字符串末尾没有三个空格导致无限循环 if (( j > ${#1} - 2 )); then break fi done # 提取从i到j-1的摩尔斯码片段(长度是j - i) morse_segment="${1:i:j-i}" # 用正确的摩尔斯码片段作为数组键,获取对应的字母 printf '%s' "${letter[$morse_segment]}" # 更新i为当前j的位置,处理下一段 i=$j
3. 关键细节解释
- 字符串比较用
[[ ]]:[[是Bash专门用来处理字符串和文件条件判断的语法,支持!=等字符串比较操作,不会把字符串当成数值处理,完美解决语法错误。 - 正确的字符串切片:Bash的切片语法是
${var:start:length},你原来的${1:i:j}是从i开始取j个字符,这完全不对——我们需要取的是从i到j之间的片段,长度应该是j - i,这样才能拿到完整的摩尔斯码字母串,作为数组的键去匹配对应的英文。 - 边界保护:如果输入的摩尔斯码最后没有三个空格(比如字符串结尾就是最后一个字母),循环会一直跑下去,加个
j > ${#1} - 2的判断(因为要取3个字符,j最多只能到字符串长度-2的位置),能避免无限循环。
4. 额外检查点
确保你的letter数组的键是纯摩尔斯码的点/划字符串(比如letter[".-"]="A"),而不是带空格的,这样提取的morse_segment才能正确匹配数组下标。
内容的提问来源于stack exchange,提问作者InterLinked
相关产品推荐
相关产品推荐

