【shell】索引数组&关联数组

一、索引数组

shell中的索引数组,可通过declare -a xxx显式声明(shell中declare用来声明一个变量类型,-a参数表示声明后面的变量为数组类型),也可以不声明直接对一个变量应用数组相关的操作变为数组,比如arr[3]=1这种方式直接赋值,shell也会将arr当作一个数组看待。

声明只是增加代码可读性,对代码逻辑无影响。即使声明为数组类型,依然可以作为单变量赋值。

索引数组在arr=(value1 value2 value3 ...)的方式初始化时,默认的索引下标index是0起始的整数,0,1,2,…。

对索引数组的赋值arr[index]=value,相同index赋值时会覆盖,且index不强制要求连续,可间断赋值。间断赋值时${#arr[@]}${#arr[*]}求数组长度时仅会统计实际存在的索引数量,被间断的索引不会参与统计。

shell数组中的特点:支持稀疏索引

删除某个位置索引可以通过unset arr[index],删除后该位置索引不会参与数组长度的统计。

比如执行下面这段代码的输出:

#!/bin/bash

arr=(1 2 3)
arr[5]=4
arr['7']=5
echo "获取数组的值: ${arr[*]}"
echo "获取数组的值: ${arr[@]}"
echo "获取数组长度: ${#arr[*]}"
echo "获取数组长度: ${#arr[@]}"
echo "获取数组的键: ${!arr[*]}"
echo "获取数组的键: ${!arr[@]}"

echo "删除位置1的索引元素: ---------"
unset arr[1]

echo "获取数组的值: ${arr[*]}"
echo "获取数组的值: ${arr[@]}"
echo "获取数组长度: ${#arr[*]}"
echo "获取数组长度: ${#arr[@]}"
echo "获取数组的键: ${!arr[*]}"
echo "获取数组的键: ${!arr[@]}"

# 获取数组的值: 1 2 3 4 5
# 获取数组的值: 1 2 3 4 5
# 获取数组长度: 5
# 获取数组长度: 5
# 获取数组的键: 0 1 2 5 7
# 获取数组的键: 0 1 2 5 7
# 删除位置1的索引元素: ---------
# 获取数组的值: 1 3 4 5
# 获取数组的值: 1 3 4 5
# 获取数组长度: 4
# 获取数组长度: 4
# 获取数组的键: 0 2 5 7
# 获取数组的键: 0 2 5 7

索引数组的下标只会是整数,尽管shell中默认将所有字符当作字符串,但在arr[index]=value形式赋值时shell会自动将字符解释为整数(index必须是可解释为整数类型的字符串)。

!在索引数组中使用字符串当做键尽管不会报错,但可能会导致数组运算上的一些逻辑的错误。

二、关联数组

shell中的关联数组在bash4及以上才开始支持。查看bash版本bash --version

shell中的关联数组类似于python中的字典,允许键为字符串类型。使用前必须通过declare -A xxx声明。

关联数组的增删改查操作都和上面索引数组类似,同名索引也会相互覆盖,不多余说明了,唯一需要注意的是,无论关联数组的键可否被解释为整数类型,都会当做字符串类型看待。且关联数组不支持0起始的整数型下标索引。

#!/bin/bash

declare -A arr
arr=([a]=1 [b]=2 [c]=3)
arr[1]=4

echo "获取数组的值: ${arr[*]}"
echo "获取数组的值: ${arr[@]}"
echo "获取数组长度: ${#arr[*]}"
echo "获取数组长度: ${#arr[@]}"
echo "获取数组的键: ${!arr[*]}"
echo "获取数组的键: ${!arr[@]}"

echo "删除键为'1'的索引元素: ---------"
unset arr[1]

echo "获取数组的值: ${arr[*]}"
echo "获取数组的值: ${arr[@]}"
echo "获取数组长度: ${#arr[*]}"
echo "获取数组长度: ${#arr[@]}"
echo "获取数组的键: ${!arr[*]}"
echo "获取数组的键: ${!arr[@]}"

# 获取数组的值: 1 2 3 4
# 获取数组的值: 1 2 3 4
# 获取数组长度: 4
# 获取数组长度: 4
# 获取数组的键: a b c 1
# 获取数组的键: a b c 1
# 删除键为'1'的索引元素: ---------
# 获取数组的值: 1 2 3
# 获取数组的值: 1 2 3
# 获取数组长度: 3
# 获取数组长度: 3
# 获取数组的键: a b c
# 获取数组的键: a b c

tips!

1.数组赋值时是否使用引号的区别

不带引号赋值,会将所有输入元素按照空格分隔。
带引号赋值,可以将引号中的内容识别为一个整体,即使引号中的元素包含空格。

至于单双引号的区别,在于是否需要变量或命令替换。

#!/bin/bash
arr1=(a b c d)
arr2=("a b" "c d")
for item in "${arr1[@]}"; do
    echo $item
done
echo "-----"
for item in "${arr2[@]}"; do
    echo $item
done

# a
# b
# c
# d
# -----
# a b
# c d

2.数组读取时是否使用引号的区别

和2类似,不加:无论数组中的元素在赋值时是何种形式,在读取时默认都按照空格拆分为多个独立元素。
加:会保持赋值时元素个数的独立性。

#!/bin/bash

arr=("a b" "c d")
for item in ${arr[@]}; do
    echo $item
done
echo "-----"
for item in "${arr[@]}"; do
    echo $item
done

# a
# b
# c
# d
# -----
# a b
# c d

3.*@的使用区别

主要分为数组长度统计和遍历两个场景。

${#arr[*]}${#arr[@]}获取数组长度时无区别,且无论加不加引号,获取的都是数组的实际长度,但推荐后者,更符合习惯。

#!/bin/bash

arr=("a b" "c d")
echo ${#arr[*]}
echo ${#arr[@]}
echo "${#arr[*]}"
echo "${#arr[@]}"

# 2
# 2
# 2
# 2


在遍历数组时,主要区别在于读取数组时是否加双引号。

  • 不加引号:无区别,不保证元素的独立性,都是按照空格分隔为多个元素遍历输出。元素中如果包含空格也会被拆分输出。
  • 加引号:@会保持数组中元素的独立性,实际有几个输出几次,元素可以包含空格不被拆分;*会将数组中所有元素按照空格拼接为一个字符串输出。
#!/bin/bash

arr=("a b" "c d")
for item in ${arr[*]}; do
    echo $item
done
echo "-----"
for item in ${arr[@]}; do
    echo $item
done
echo "-----"
for item in "${arr[*]}"; do
    echo $item
done
echo "-----"
for item in "${arr[@]}"; do
    echo $item
done

# a
# b
# c
# d
# -----
# a
# b
# c
# d
# -----
# a b c d
# -----
# a b
# c d

4.获取数组的键索引

shell中数组默认获取输出数组的值,获取数组的键可以通过${!arr[*]}${!arr[@]},二者的使用区别同上面3。

索引数组:

#!/bin/bash

declare -A arr
arr['a c']=1
arr['b']=2

for item in ${!arr[*]}; do
    echo $item
done
echo "-----"
for item in ${!arr[@]}; do
    echo $item
done
echo "-----"
for item in "${!arr[*]}"; do
    echo $item
done
echo "-----"
for item in "${!arr[@]}"; do
    echo $item
done

# a
# c
# b
# -----
# a
# c
# b
# -----
# a c b
# -----
# a c
# b

关联数组:

#!/bin/bash

arr=(a b c)

for item in ${!arr[*]}; do
    echo $item
done
echo "-----"
for item in ${!arr[@]}; do
    echo $item
done
echo "-----"
for item in "${!arr[*]}"; do
    echo $item
done
echo "-----"
for item in "${!arr[@]}"; do
    echo $item
done

# 0
# 1
# 2
# -----
# 0
# 1
# 2
# -----
# 0 1 2
# -----
# 0
# 1
# 2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值