如何检查 bash for 循环中的不等式?
How to check for inequality in bash for loop?
我在 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 循环,这样我就不会收到关于无效语法的错误?
这种形式的 for
循环 仅 用于算术运算。您需要使用 while
循环来代替:
j=$i
while [[ ${1:j:3} != " " ]]; do
sleep 0.1
j=$((j+1))
done
Basically, what I need is for the loop to run through the characters
in a string until it finds three consecutive spaces. The string
contains Morse code, and each letter is separated by 3 characters
(because in American Morse, letters can contain 0, 1, or 2 spaces, so
3 is the minimum letter delimiter).
好吧,这似乎是一种奇怪的方式。 shell 比通过遍历索引扫描字符串有更好的机制来完成这项任务。例如,
# the value of , with the longest suffix matching glob pattern " *" removed.
letter=${1%% *}
我不清楚你的示例代码中 sleep 0.1
的目的,但如果你只是模拟通过摩尔斯电码接收信号的时间(完成不同摩尔斯字母的不同时间length),那么可以单独编址。
Afterward, I convert what I have detected to be a complete Morse
letter to English and print it out, and then move on to the next Morse
characters.
所以我会更像这样:
morse=
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
这涵盖了 所有 摩尔斯字母的循环,顺便说一下,不只是一个。
在 shell 代码中按索引遍历字符串不一定是错误的,但它有不好的代码味道。
我在 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 循环,这样我就不会收到关于无效语法的错误?
这种形式的 for
循环 仅 用于算术运算。您需要使用 while
循环来代替:
j=$i
while [[ ${1:j:3} != " " ]]; do
sleep 0.1
j=$((j+1))
done
Basically, what I need is for the loop to run through the characters in a string until it finds three consecutive spaces. The string contains Morse code, and each letter is separated by 3 characters (because in American Morse, letters can contain 0, 1, or 2 spaces, so 3 is the minimum letter delimiter).
好吧,这似乎是一种奇怪的方式。 shell 比通过遍历索引扫描字符串有更好的机制来完成这项任务。例如,
# the value of , with the longest suffix matching glob pattern " *" removed.
letter=${1%% *}
我不清楚你的示例代码中 sleep 0.1
的目的,但如果你只是模拟通过摩尔斯电码接收信号的时间(完成不同摩尔斯字母的不同时间length),那么可以单独编址。
Afterward, I convert what I have detected to be a complete Morse letter to English and print it out, and then move on to the next Morse characters.
所以我会更像这样:
morse=
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
这涵盖了 所有 摩尔斯字母的循环,顺便说一下,不只是一个。
在 shell 代码中按索引遍历字符串不一定是错误的,但它有不好的代码味道。