如何检查bash for loop中的不平等?

时间:2019-07-19 14:07:27

标签: bash for-loop inequality

我在bash脚本中有以下for循环:

for (( j = i; ${1:j:3} != "   "; j=j + 1 ))
do
    sleep 0.1
done
printf '%s' "${letter[${1:i:j}]}"
i=$j

运行时,它将导致以下错误的无限循环:

/home/com/morsecoder.sh: line 188: letter: bad array subscript
/home/com/morsecoder.sh: line 184: ((: ... !=    : syntax error: operand expected (error token is "... !=    ")

问题在第一行;错误的数组下标错误几乎可以肯定是它的副产品。

我可以看到该错误是由我的${1:j:3} != " "引起的。基本上,我需要循环运行字符串中的字符,直到找到三个连续的空格为止。该字符串包含莫尔斯电码,每个字母由3个字符分隔(因为在美国莫尔斯电码中,字母可以包含0、1或2个空格,因此3是最小字母分隔符)。

然后,我将检测到的完整的摩尔斯字母转换为英文,然后打印出来,然后移至下一个摩尔斯字符。

printf部分似乎工作正常,但是这里的错误让我感到困惑。我检查了一下,是否正确使用了(())以及!=来检查不平等。我还尝试将${1:j:3}括在引号中,但这没有任何作用。我该如何改写for循环,以免收到无效语法的错误?

2 个答案:

答案 0 :(得分:4)

for循环的这种形式仅 用于算术运算。您需要改用while循环:

j=$i
while [[ ${1:j:3} != "   " ]]; do
    sleep 0.1
    j=$((j+1))
done

答案 1 :(得分:2)

  

基本上,我需要的是循环运行字符   直到找到三个连续的空格为止。字符串   包含摩尔斯电码,每个字母由3个字符分隔   (因为在美国摩尔斯语中,字母可以包含0、1或2个空格,所以   3是最小字母分隔符。

这似乎是一个奇怪的方法。与通过遍历索引扫描字符串相比,shell具有更好的机制来完成此任务。例如,

# the value of $1, with the longest suffix matching glob pattern "   *" removed.
letter=${1%%    *}

您对示例代码中的sleep 0.1的用途尚不清楚,但是如果您只是简单地模拟通过摩尔斯电码接收信号的时间(对于摩尔斯长度不同的字母,请使用不同的时间完成)然后可以单独解决。

  

然后,我将检测到的信息转换为完整的莫尔斯电码   英文字母并打印出来,然后移至下一个摩尔斯   字符。

所以我会更像这样:

morse=$1

while [[ -n "$morse" ]]; do
  # extract the next letter
  next_let=${morse%%    *}
  # sleep for a duration based on the (Morse) length of the letter
  sleep "0.${#next_let}"
  # print the corresponding decoded Latin letter
  printf '%s' "${letter[${next_let}]}"
  # remove the Morse letter and its delimiter, if any
  morse=${morse:$((${#next_let}+3))}
done

顺便说一句,这涵盖了您遍历所有所有摩尔斯字母的过程。

在外壳代码中按索引遍历字符串不一定是错误的,但是有不好的代码味道。