是否可以在 bash 脚本中创建多维数组?
这是我的 3 个数组:
arrayCITY=( NewYork LasVegas Detroit )
arraySTREET=( RoadStreet TreeStreet HighStreet )
arrayNUMBER=( 20 455 300 )
现在我想将这 3 个数组放入一个数组中 - 这可能吗?然后我想在txt文件中显示它们。现在我这样做:
for ((i=0; i<${#arrayCITY[*]}; i++));do
echo "${arrayCITY[i]} ${arraySTREET[i]} ${arrayNUMBER[i]}" >> TEXT.txt
done
答案1
从man 1 bash
:
Arrays
Bash provides one-dimensional indexed and associative array variables. Any variable
may be used as an indexed array; the declare builtin will explicitly declare an
array. There is no maximum limit on the size of an array, nor any requirement that
members be indexed or assigned contiguously. Indexed arrays are referenced using
integers (including arithmetic expressions) and are zero-based; associative arrays
are referenced using arbitrary strings. Unless otherwise noted, indexed array
indices must be non-negative integers.
关键词:
Bash 提供一维索引和关联数组变量。
所以,不,bash 不支持多维数组。
答案2
我刚才遇到了这个。有一个相当简单的解决方案对我有用。我想使用包含设备名称和屏幕位置的数组来显示设备的按键映射。我执行了以下操作:我使用分隔符将设备名称和关联的屏幕位置连接成一个字符串(在我的例子中,我使用 .
)我知道它不会出现在我的任何价值观中。然后,我常常cut
在需要时将复合值分解为它们的组成部分。可能有一种更干净、更简单的方法来做到这一点,但这只是为了表明您可以在某种程度上在 bash 中创建多维数组,即使它不支持它:
#!/bin/bash
# List of devices and screen positions for key maps.
DEV_LIST=( g13.+2560+30 g510s.+3160+30 g502.+2560+555 )
# This just echoes the device name and the screen position.
for DEV in "${DEV_LIST[@]}"; do
DEVICE=$(echo $DEV | cut -f1 -d.)
SCREEN_POSITION=$(echo $DEV | cut -f2 -d.)
echo "$DEVICE"
echo "$SCREEN_POSITION"
done
exit
这有点类似于Coop.Computer的回答。
答案3
这是一个适合我的解决方案。如果我们首先像这样设置数组:
arrayCSR=( Placeholder_for_0_spot NewYork RoadStreet 20 LasVegas TreeStreet 455 Detroit HighStreet 300 )
占位符的存在是为了避免处理 0 索引。
然后,每个“行”是任何可以被3整除的数字,每个“列”比“行”数字小1或2。
${arrayCSR[${3}]} is 20
${arrayCSR[${2}]} is RoadStreet
${arrayCSR[${1}]} is NewYork
示例脚本如下:
arrayCSR=( CsR NewYork RoadStreet 20 LasVegas TreeStreet 455 Detroit HighStreet 300 )
for p in $( seq 1 ${#arrayCSR[*]} )
do
if [[ "${arrayCSR[${p}]}" == "" ]] # Don't run if empty
then
true
elif [[ $((p % 3 )) -eq 0 ]] # We have 3 "columns" in the array
then
echo " ${arrayCSR[$(( p - 2 ))]} ${arrayCSR[$(( p - 1))]} ${arrayCSR[${p}]}"
fi
done
因此任何能除以 3 的索引都表示一个“行”,也表示该行中的第三个“列”。要获得第二个和第一个“列”,请相应地减去 1 或 2。
如果需要的话,这也可以扩大规模。
更新:下面是我用来加载文件名的字符串替换数组的代码。第一个数组从文件加载,然后分成 2 个单独的数组。
readarray -t string_replace < ~/scripts/string_replace.lst # List of things to remove from name
for p in $( seq 0 ${#string_replace[*]} ); do
old_name_element[${p}]="${string_replace[${p}]%%,*}"
new_name_element[${p}]="${string_replace[${p}]:$((${#old_name_element[${p}]}+1))}"
done
string_replace=() # Clear old array
答案4
尽管我很喜欢 Bash,但有时切换到其他语言也是有意义的。在 Python 中使用字典非常简单:
#!/usr/bin/env python3
cities = {
"New York": { "Street": "Roadstreet", "Number": 20 },
"Las Vegas": { "Street": "TreeStreet", "Number": 455 }
}
for city in cities:
print(str(city) + ": " + str(cities[city]["Street"])
+ " " + str(cities[city]["Number"]))
运行此命令会产生:
./cities.py
New York: Roadstreet 20
Las Vegas: TreeStreet 455