gpt4 book ai didi

linux - Bash 将命令解析为二维数组

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:02:48 27 4
gpt4 key购买 nike

我想制作一个脚本,列出所有可用的 MIDI 设备并提示用户选择一个,然后为每个音符分配快捷方式。我设法使用 aseqdump -l 获得了所有设备的列表。就我而言,这输出:

 Port    Client name                      Port name
0:0 System Timer
0:1 System Announce
14:0 Midi Through Midi Through Port-0
20:0 UMC404HD 192k UMC404HD 192k MIDI 1
28:0 Launchpad S Launchpad S MIDI 1

用我最少的技能,我制作了一个脚本,在每一行之前添加了一个数字,所以它看起来像这样:

    Port    Client name                      Port name
1) 0:0 System Timer
2) 0:1 System Announce
3) 14:0 Midi Through Midi Through Port-0
4) 20:0 UMC404HD 192k UMC404HD 192k MIDI 1
5) 28:0 Launchpad S Launchpad S MIDI 1

然后系统会提示用户根据左侧的数字选择设备。所有的乐趣和游戏,但我不知道如何只读取设备名称。例如,如果用户输入“4”,我希望我的 mDevice 变量等于“UMC404HD 192k”,这样我就可以调用 aseqdump -p $(mDevice) 并监控其事件。

我尝试逐字阅读命令输出,但这似乎毫无用处,因为每个字段中的字数从 1 到 5 甚至更多不等。是否可以将此命令的输入解析为二维数组,其中一维将存储设备?例如,我理想情况下有

mDevicesArray[0] = { "0:0", "System, "Timer"} 
mDevicesArray[1] = { "0:1", "System", "Announce"}
...
mDevicesArray[4] = { "28:0", "Launchpad S", "Launchpad S MIDI 1"}

然后使用这个数组进一步处理设备。

最佳答案

bash 没有二维数组。只要执行速度不是什么大问题,您就可以使用关联数组来模拟:

$ cat ./tst.sh
#!/bin/env bash

declare -A mDevicesArray

mDevicesSet() {
local rowNr="$1" colNr
shift
for (( colNr=1; colNr<=$#; colNr++ )); do
mDevicesArray["${rowNr},${colNr}"]="${!colNr}"
done
}

mDevicesSet 1 '0:0' 'System' 'Timer'
mDevicesSet 2 '0:1' 'System' 'Announce'
mDevicesSet 3 '14:0' 'Midi Through' 'Midi Through Port-0'
mDevicesSet 4 '20:0' 'UMC404HD 192k' 'UMC404HD 192k MIDI 1'
mDevicesSet 5 '28:0' 'Launchpad S' 'Launchpad S MIDI 1'

printf '%s\n' "${mDevicesArray[4,2]}"

$ ./tst.sh
UMC404HD 192k

否则还有其他各种解决方法,例如使用我不推荐的 eval,或者为了简单、稳健和高效,您可以只使用 mDevicesArray1[1]="0:0"; mDevicesArray2[1]="系统"; mDevicesArray3[1]="Timer" 等等,然后简单地编写函数来访问数组,就像它们是 2D 一样,例如:

$ cat tst.sh
#!/bin/bash

mDevicesSet() {
local rowNr="$1"
shift
mDevicesArray1["$rowNr"]="$1"
mDevicesArray2["$rowNr"]="$2"
mDevicesArray3["$rowNr"]="$3"
}

mDevicesGet() {
local rowNr=$1 colNr=$2 val
case $colNr in
1 ) val="${mDevicesArray1[$rowNr]}" ;;
2 ) val="${mDevicesArray2[$rowNr]}" ;;
3 ) val="${mDevicesArray3[$rowNr]}" ;;
esac
printf '%s\n' "$val"
}

mDevicesSet 1 '0:0' 'System' 'Timer'
mDevicesSet 2 '0:1' 'System' 'Announce'
mDevicesSet 3 '14:0' 'Midi Through' 'Midi Through Port-0'
mDevicesSet 4 '20:0' 'UMC404HD 192k' 'UMC404HD 192k MIDI 1'
mDevicesSet 5 '28:0' 'Launchpad S' 'Launchpad S MIDI 1'

printf '%s\n' "$(mDevicesGet 4 2)"

$ ./tst.sh
UMC404HD 192k

与使用关联数组相比,虽然执行速度更快,但索引数组方法的缺点是您有一个硬编码的列数 (3) 并且每行必须具有相同的列数并且更难扩展超过 2 个索引。

关于linux - Bash 将命令解析为二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56569377/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com