在Shell编程中同样支持数组操作,我们可以在Shell脚本对数组进行增删改查。
在Shell中用户可以像其他编程语言一样通过元素值来定义数组,语法如下:
array[key]=value
array表示数组的名称,key参数表示数组元素的索引,通常是一个整数,value为元素的值,需要注意的是,数组的下标从零开始。
#! /usr/bin/env bash
#指定数组元素值
array[1]=hello
array[3]=world
echo "${array[1]} ${array[3]}"
Output:
$ sh test.sh
hello world
使用declare定义数组的语法为:declare -a array
#! /usr/bin/env bash
#通过declare定义数组
declare -a MyArray
MyArray[0]=hello
MyArray[1]=world
echo "${MyArray[0]} ${MyArray[1]}"
Output:
$ sh test.sh
hello world
另外shell还可以定义关联数组:declare -A ARRAY_NAME
,定义关联数组 即可自定义索引,可为字符、字符串等。
#! /usr/bin/env bash
#通过declare定义关联数组
declare -A MyArray
MyArray[sex]=man
MyArray[name]=random_w
MyArray[age]=18
echo "My name is ${MyArray[name]}, I am ${MyArray[age]} years old, and I am a ${MyArray[sex]}"
Output:
$ sh test.sh
My name is random_w, I am 18 years old, and I am a man
在某些时候,用户可能需要一次性为数组的所有元素提供一个值,此时,用户可以通过元素值集合的形式来定义数组,基本语法如下:
array=( v0 v1 v2 ... vn)
array表示数组的名称,所有元素以空格隔开。
#! /usr/bin/env bash
#通过集合定义数组
MyArray=(1 2 3 4)
#MyArray[@]表示MyArry的所有元素
echo "${MyArray[@]}"
Output:
$ sh test.sh
1 2 3 4
注意:在使用集合的时候,如果某个值中包含空格,则需要使用单引号或者双引号将值括起来。
这种方法和通过指定元素值来定义数组有点类似,语法如下:
array=([0]=value0 [1]=value1 [2]=value2 ... [n]=value[n])
在这里array五为数组的名称,等号右边的圆括号表示数组元素及其值,用这种方式定义数组,索引可以是不连续的。
#! /usr/bin/env bash
#通过集合定义数组
MyArray=([0]=1 [2]=2 [3]=3 [4]=4)
#MyArray[@]表示MyArry的所有元素
echo "${MyArray[@]}"
Output:
$ sh test.sh
1 2 3 4
在Shell中所有的变量实际上都可以当作数组变量来使用。
#! /usr/bin/env bash
#定义字符串
Str="Hello World!"
echo "${Str[0]} ${Str[@]} ${Str[*]}"
Output:
$ sh test.sh
Hello World! Hello World! Hello World!
从上面的例子我们可以看出字符串也可以作为数组来使用,但是该数组只有一个元素。
注意:符号@和*都是通配符,表示匹配的所有元素,所以我们可以使用${array[@]}或者${array[*]表示数组的所有元素。
按索引方式赋值和通过指定元素值来定义数组是类似的,语法为:array[n]=Value
array为数组的名称,n为要赋值的元素索引,Valuen为对应的元素值。
#! /usr/bin/env bash
#定义数组
Student=( random1 random2 random3)
echo "All Student are: ${Student[@]}"
#给数组赋值
Student[1]=hello
Student[3]=world
echo "All Student are: ${Student[@]}"
Output:
$ sh test.sh
All Student are: random1 random2 random3
All Student are: random1 hello random3 world
通过集合给数组赋值和通过集合定义数组的语法是相同的:array=( v0 v1 v2 ... vn)
当给数组提供一组值的时候,Shell会从第一个元素开始,依次将这些值赋值给每个元素,当新值的数量超过原来的数组的时候,Shell就会在数组末尾添加新的元素,当新的值的个数少于原来的长度,Shell就会将新的值从第一个元素开始赋值,然后删除超出的元素。
#! /usr/bin/env bash
#定义数组
Student=( random1 random2 random3)
echo "All Student are: ${Student[@]}"
#给数组赋值
Student=( random_w1 random_w2 random_w3 random_w4)
echo "All Student are: ${Student[@]}"
#给数组赋值
Student=( random_w1 random_w2)
echo "All Student are: ${Student[@]}"
Output:
$ sh test.sh
All Student are: random1 random2 random3
All Student are: random_w1 random_w2 random_w3 random_w4
All Student are: random_w1 random_w2
在Shell中,在通过索引给数组元素赋值时,如果指向的索引不存在,则Shell会自动添加一个新的元素,并赋值给数组。
#! /usr/bin/env bash
#定义数组
Student=( random1 random2 random3)
echo "All Student are: ${Student[@]}"
#给数组赋值
Student[3]=random4
echo "All Student are: ${Student[@]}"
Output:
$ sh test.sh
All Student are: random1 random2 random3
All Student are: random1 random2 random3 random4
在实际情况中,比较常见的就是通过循环给数组赋值,下面举个例子:
#! /usr/bin/env bash
for i in {1..10}
do
array[$i]=$i
done
echo "${array[@]}"
Output:
$ sh test.sh
1 2 3 4 5 6 7 8 9 10
前面已经说过,我们和可以通过数组的方式调用字符串,同样,我们可以使用调用字符串的形式调用数组的第一个元素:
#! /usr/bin/env bash
array=(1 2 3 4)
echo "${array}"
Output:
$ sh test.sh
1
这个我们在前面已经用过了,语法为:array[n]
,表示调用数组下标为n的元素,这里不再举例。
在Shell中我们可以使用$#来获取数组的长度。该操作符的基本语法如下:
${#array[@]}
或者${#array[*]}
通过$#我们还可以获取某个数组元素的长度:
${#array[n]}
#! /usr/bin/env bash
#给数组赋值
Student=( random_w1 random_w2 random_w3 random_w4)
echo "All Student are: ${Student[@]}, There are ${#Student[@]} students in all"
Output:
$ sh test.sh
All Student are: random_w1 random_w2 random_w3 random_w4, There are 4 students in all
这个是通过循环给数组赋值的逆过程:
#! /usr/bin/env bash
#给数组赋值
Student=( random_w1 random_w2 random_w3 random_w4)
for ((i=0;i<${#Student[@]};i++))
do
echo "Student: ${Student[$i]}"
done
Output:
$ sh test.sh
Student: random_w1
Student: random_w2
Student: random_w3
Student: random_w4
我们可以通过{array[@]}
者${array[*]}
方式引用数组的所有元素,前面我们已经用过了,这里就不举例了。
这里所说的切片是指截取数组的部分元素或者某个元素的福分内容,例如获取某个数组的第二个元素开始到第五个元素,获取切片的语法如下:
${array[@|*]:start:length}
语法中array为数组的名称,start为下标开始的地方,length为要截取的长度,通过上面的语法我们获取到的是一个字符串,如果想获取到的依然是一个数组,只需要给两边加上括号即可,如:
(${array[@|*]:start:length})
#! /usr/bin/env bash
#给数组赋值
Release=( Debian Redhat Ubuntu Suse Fedora UTS CentOS)
echo "${Release[@]2:3}"
Release=(${Release[@]:2:3})
for ((i=0;i<${#Release[@]};i++))
do
echo "${Release[$i]}"
done
Output:
$ sh test.sh
Suse Fedora UTS CentOS
Ubuntu
Suse
Fedora
Shell中除了可以对数组进行切片外,还可以对数组中的元素进行切片,语法如下:
${array[n]:start:length}
#! /usr/bin/env bash
#给数组赋值
Release=( Debian Redhat Ubuntu Suse Fedora UTS CentOS)
#这里截取CentOS的最后两个字符
echo "${Release[6]:4:2}"
Output:
$ sh test.sh
OS
在Shell中用户还可以对数组元素进行替换操作,这里的替换是指将某个数组的部分内容用其他的字符串俩代替,但是并不影响原来数组的值,其基本语法如下:
${array[@|*]/pattern/replacemant}
在上面的语法中,array表示数组的名称,pattern表示要替换的字符串,replacement表示用来替换的字符串。
#! /usr/bin/env bash
#给数组赋值
Release=( Debian Redhat Ubuntu Suse Fedora UTS CentOS)
echo "New array: ${Release[@]/Ubuntu/random_w}"
echo "Old array: ${Release[@]}"
Output:
$ sh test.sh
New array: Debian Redhat random_w Suse Fedora UTS CentOS
Old array: Debian Redhat Ubuntu Suse Fedora UTS CentOS
与删除其他Shell变量一样,我们可以使用unset删除数组的元素:
unset array[n]
#! /usr/bin/env bash
#给数组赋值
Release=( Debian Redhat Ubuntu Suse Fedora UTS CentOS)
unset Release[2]
echo "New array: ${Release[@]}"
Output:
$ sh test.sh
New array: Debian Redhat Suse Fedora UTS CentOS
同样我们可是使用unset命令删除数组
unset array
#! /usr/bin/env bash
#给数组赋值
Release=( Debian Redhat Ubuntu Suse Fedora UTS CentOS)
unset Release
echo "New array: ${Release[@]}"
Output:
$ sh test.sh
New array:
在Shell中用户可以通过下面的方式实现数组的赋值:
newarray=("$array[@]")
#! /usr/bin/env bash
#给数组赋值
Release=( Debian Redhat Ubuntu Suse Fedora UTS CentOS)
Release2=("${Release[@]}")
echo "Release2: ${Release2[@]}"
Output:
$ sh test.sh
Release2: Debian Redhat Ubuntu Suse Fedora UTS CentOS
连接两个数组的方式也很简单,语法如下:
("$array1[@]" "$array2[@]")
#! /usr/bin/env bash
#给数组赋值
Release1=( Debian Redhat Ubuntu)
Release2=( Suse Fedora UTS CentOS)
Release=("${Release1[@]}" "${Release2[@]}")
echo "Release2: ${Release[@]}"
```bash
$ sh test.sh
Release2: Debian Redhat Ubuntu Suse Fedora UTS CentOS
在Shell中,用户可以将普通文本的内容直接加载到数组,文件的每一行是数组的一个元素:
[root@random_wz ~]# cat student.txt
random_w1
random_w2
random_w3
random_w4
#! /usr/bin/env bash
#给数组赋值
Student=(`cat "student.txt"`)
echo "Student: ${Student[@]}"
Output:
[root@random_wz ~]# sh test.sh
Student: random_w1 random_w2 random_w3 random_w4