3

我正在遍历一个整数数组${startTimes}(音频文件中的标记位置,在样本中)并使用bc将这些整数转换为毫秒。我将结果传递到一个新数组${msValuesArray}中。如果我一次运行每个数组元素,它工作正常。如果我for循环运行它:

for i in $(seq 0 ${#startTimes[@]}); do 
    msValuesArray+=($(bc <<< ${startTimes[i]}/44.1))
done

结果${msValuesArray}包含预期结果,但终端输出(standard_in) 1: parse error.

虽然我打算在 shell 脚本中使用它,并且在阅读了此处的其他问题后,我了解到添加#!/bin/bash到命令的开头可以避免解析错误,但我仍然不明白以下内容:

a)为什么在循环也有效的情况下手动将${startTimes}元素传递到bc工作而没有解析错误for,但输出解析错误(在shell脚本之外)?

b) 尽管有解析错误,我还是得到了我想要的结果数组。我应该忽略错误吗?

c)当添加#!/bin/bash到命令的开头(仍然在 shell 脚本之外,只是在命令行中)为什么结果无法访问?(输入echo ${msValuesArray[@]}返回一个空数组。)

d) 在 shell 脚本中运行时,是否发生了同样的错误,但只是没有打印到终端?

任何帮助表示赞赏。谢谢。

4

2 回答 2

3

您可以直接遍历数组,而不是通过索引:

for t in "${startTimes[@]}"; do
    msValuesArray+=($(bc <<< "$t / 44.1"))
done

这使得循环更容易阅读。

你得到一个解析错误,因为你试图访问一个不存在的元素(见 John1024 的答案),所以bc看到/ 44.1. 你不应该忽略这个错误。

您应该引用您的 here-string,即使在这种情况下它似乎不会导致问题1

如果你#!/bin/bash只是在命令行输入,它根本没有任何作用,它只是被认为是一个注释。它只作为脚本的第一行做一些事情,即指示应该使用什么解释器。如果如您的评论所示,您在一行中输入整个内容

#!/bin/bash; for ... (etc) ...

什么都没有发生。这只是一个评论。

最后,你正在截断你的结果。如果你想让它们更精确,你可以设置scale一个合理的值,如

bc <<< "scale = 3; $t / 44.1"

1(不需要的)分词和通配等问题。本文很好地概述了引用的方式和原因。

于 2017-08-28T21:34:45.500 回答
3

你有一个off-by-1问题。请注意,使用您的示例 startTimesseq生成 10 个数字:

$ startTimes=(0 87053 91463 190062 194472 290520 294930 387582 391992)
$ seq 0 ${#startTimes[@]}
0
1
2
3
4
5
6
7
8
9

问题是 startTimes 只有 9 个条目:

$ declare -p startTimes
declare -a startTimes=([0]="0" [1]="87053" [2]="91463" [3]="190062" [4]="194472" [5]="290520" [6]="294930" [7]="387582" [8]="391992")

i=9, startTimes[9] 评估为空字符串并导致bc您看到的错误:

$ i=9; msValuesArray+=($(bc <<< ${startTimes[i]}/44.1))
(standard_in) 1: syntax error

或者,更直接地:

$ bc <<<"/44.1"
(standard_in) 1: syntax error
于 2017-08-28T21:35:49.350 回答