我在BASH中使用变量名称连接或替换时遇到了一些问题。鉴于:
#!/bin/bash
Audio1=(0:ita, 96k, AAC, 2.0, s16le, 48000) # audio stream definitions
Audio2=(1:rus, 128k, AAC, 2.0, s16le, 48000) # for use in ffmpeg or
Audio3=(2:klg, 96k, AAC, 1.0, s16le, 48000) # avconv
# and so on, now processing the audio streams
for ((i=1 ; i<=8 ; i++)) ; do
Audio="Audio$i"
Audio=${!Audio}
if [ ${#Audio[0]} -gt 0 ] ; then
# do the job with $Audio, here examplaryly:
echo ${Audio[@]}
fi
done
预期结果是:
0:ita, 96k, AAC, 2.0, s16le, 48000
1:rus, 128k, AAC, 2.0, s16le, 48000
2:klg, 96k, AAC, 1.0, s16le, 48000
我得到了:
0:ita,
1:rus,
2:klg,
这只是解决方案的一半,因为每个源数组只复制了第一个元素,而不是完全复制到工作数组$ Audio中。在PHP中,我会简单地通过以下方式编写变量名称替换:
for ($i=1; $i<=8; $i++) {
$Audio = ${'Audio'.$i}; // ← that’s all the magic in PHP ;-)
if (isset($Audio[0])) {
// blabla
}
}
不幸的是,我不能将PHP用于此应用程序。当然,这是我在BASH的第一个脚本之一。切换到任何其他编码(例如,许多简单变量而不是少数阵列)不是一种选择。我必须使用这些预设。那么,我的错在哪里,出了什么问题?
问候 - 伯特
答案 0 :(得分:1)
在BASH版本4.3+中,您可以使用declare -n
:
for ((i=1 ; i<=3; i++)) ; do
declare -n Audio="Audio$i"
if [[ ${#Audio[@]} -gt 0 ]]; then
echo "${Audio[@]}"
fi
done
0:ita, 96k, AAC, 2.0, s16le, 48000
1:rus, 128k, AAC, 2.0, s16le, 48000
2:klg, 96k, AAC, 1.0, s16le, 48000
-n
使NAME
成为对其value
命名的变量的引用。因此,在上面的代码Audio
中引用了Audio1
,Audio2
,Audio3
等中包含的值。
答案 1 :(得分:1)
不使用namerefs,你可以这样做:
Audio1=(0:ita, 96k, AAC, 2.0, s16le, 48000) # audio stream definitions
Audio2=(1:rus, 128k, AAC, 2.0, s16le, 48000) # for use in ffmpeg or
Audio3=(2:klg, 96k, AAC, 1.0, s16le, 48000) # avconv
for i in {1..3}; do
aryvar="Audio${i}[@]" # this is the special magic indirect varname
for value in "${!aryvar}"; do printf "%d\t%s\n" $i "$value"; done
# ...........^^^^^^^^^^^^ expands to elements of the array
done
输出
1 0:ita,
1 96k,
1 AAC,
1 2.0,
1 s16le,
1 48000
2 1:rus,
2 128k,
2 AAC,
2 2.0,
2 s16le,
2 48000
3 2:klg,
3 96k,
3 AAC,
3 1.0,
3 s16le,
3 48000
我错过了你想要的输出。这是:
$ for i in {1..3}; do
aryvar="Audio${i}[*]" # note the "*" not "@"
echo "${!aryvar}"
done
0:ita, 96k, AAC, 2.0, s16le, 48000
1:rus, 128k, AAC, 2.0, s16le, 48000
2:klg, 96k, AAC, 1.0, s16le, 48000