Shell编程之数组

一、字符串与列表回顾(注意与数组区分)

i="11223344"  ##字符串

在这里插入图片描述

二、数组

1、数组定义方法

(30  20  10  60  50  400   1   2   3   4   5
  
-------方法一-------
数组名=(value0 value1 value2 ........)

-------方法二--------
数组名=([0]=value [1]=value [2]=value)

-------方法三--------
列表名=“value0 value1 value2.....”
数组名=($列表名)

--------方法四--------
数组名[0]="value"
数组名[1]="value"
数组名[2]="value"

2、数组包括的数据类型

  • 数值类型

  • 字符类型:使用 " " 或 ’ ’ 定义

3、获取数组长度

[root@localhost ~]# arr=(1 2 3 4 5 6)
[root@localhost ~]# length=${#arr[*]}
[root@localhost ~]# length=${#arr[@]}
[root@localhost ~]# echo $length

在这里插入图片描述

4、获取数组列表

[root@localhost ~]# echo ${arr1[*]}
10 20 30 40 50
[root@localhost ~]# echo ${arr1[@]}
10 20 30 40 50

在这里插入图片描述

5、读取某下标赋值

[root@localhost ~]# echo ${arr2[0]}
10
[root@localhost ~]# echo ${arr2[1]}
20

在这里插入图片描述

6、数组遍历

[root@localhost ~]# arrlist=${arr1[*]}
[root@localhost ~]# echo $arrlist
10 20 30 40 50
[root@localhost ~]# for i in $arrlist
> do
> echo $i
> done

在这里插入图片描述

7、数组切片

[root@localhost ~]# echo $arrlist  #输出整个数组
10 20 30 40 50
[root@localhost ~]# echo ${arr1[*]:2:1} 
30
[root@localhost ~]# echo ${arr1[@]:2:2}
30 40
[root@localhost ~]# echo ${arr1[@]:3:2}
40 50
[root@localhost ~]# echo ${arr2[@]:4:1}
50

在这里插入图片描述

  • 在切片的时候,先将数组输出一遍,在内部进行下标赋值,与外部无关,所有没有元素也可以输出

8、数组替换

  • 替换仅仅是临时替换,重新替换需要重新赋值
arr=(1 2 3 4 5)

echo ${arr[@]/4/66}       #${数组名[@或*]/查找字符/替换字符}
echo ${arr[@] }           #并不会替换数组原有内容

arr= (${arr[@]/4/66})     #要实现改变原有数组,可通过重新赋值实现
echo ${arr[@]}

在这里插入图片描述

9、数组删除

arr=(1 2 3 4 5)
unset arr        #删除数组
echo ${arr[*]}

arr=(1 2 3 4 5)
unset arr [2]     #删除第三个元素
echo ${arr[*]}

在这里插入图片描述

10、数组追加元素

方法一:
array_ name [index]-value

方法二:
array_ name[${#array_ name[@]}]=value

方法三:
array_ name= ("${array_ name[@]}" value1 ... valueN)
#双引号不能省略,否则,当数组array_name中存在包含空格的元素时会按空格将元素拆分成多个
#不能将“@”替换为“*”,如果替换为“*”,不加双引号时与“@"的表现一*致, 加双引号时,会将数组array_ name中的所有元素作为一个元素添加到数组中
for i in "${array_ name[@]}"; do echo $i; done

方法四:
array_ name+= (value1 ......valueN)
#待添加元素必须用“()"包围起来,并且多个元素用空格分隔
  • 方法一
    在这里插入图片描述

  • 方法二
    在这里插入图片描述

  • 方法三
    在这里插入图片描述

  • 方法四

在这里插入图片描述

11、向函数传数组参数

  • 如果将数组变量作为函数参数,函数只会取数组变量的第一个值。
#!/bin/bash

test1 (){
        echo "函数接收到的参数列表为:${arry[@]}"
        newarr=($1)
        echo "新的数组的值为:${newarr[@]}"
}

#####main####

arr=(3 1 2 5 4)

echo "原始的数组列表为:${arry[@]}"

test1 $arry

在这里插入图片描述

  • 解决这个问题则需要将数组变量的值分解成单个的值,然后将这些值作为函数参数使用。在函数内部,再将所有的参数重新组合成一个新的数组变量。
#!/bin/bash

test1 (){
        echo ""函数接收到的参数列表为:$@
        newarr=($@)
        echo "函数中新的数组的值为:${newarr[*]}"
}


#####main####

arr=(3 1 2 5 4)
echo "原始的数组列表为:${arr[@]}"

test1 ${arr[*]}

在这里插入图片描述

  • 使用$@、 $# 、$1查看从数组向函数传参数的结果。
#!/bin/bash
test1(){
        echo $1
        echo $@
        echo $#
}
arr=(3 1 2 5 4)
test1 ${arr[@]}
[root@localhost ~]# bash demo4.sh 
3										    #$1是获取数组的第一个参数的值
3 1 2 5 4									#$@是获取数组的所有的值
5											#$#是获取数组的长度

在这里插入图片描述

12 、从函数中返回数组

#!/bin/bash
test1(){
	newarry=($@)								#获取函数体外定义的数组列表值,将newarry也定义为一个数组
	sum=0										#定义一个获取和的变量
	for value in ${newarry[*]}				    #使用for循环在函数体内的数组列表中取值
	do
		sum=$[$sum + $value]					#将函数体内的数组列表的值进行加法求和
	done
	echo $sum									#输出求和结果
}
arry=(10 20 30 40 50)							#定义一组函数
echo "原始数组的值为:${arry[*]}"					#输出原始数组的值
result=`test1 ${arry[*]}`						#获取函数体内输出的求和结果赋给一个变量
echo "新数组的和为:$result"						#输出变量,变量是求和结果的值


原始数组的值为:10 20 30 40 50
新数组的和为:150

在这里插入图片描述

三、数组排序算法

1、冒泡排序法

  • 类似气泡上涌的动作,会将数据在数组中从小到大或者从大到小不断地向前移动

  • 基本思想
    冒泡排序的基本思想是对比相邻的两个元素值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把大的元素移动到数组后面(也就是交换两个元素的位置),这样较小的元素就像气泡一样从底部上升到顶部。

  • 算法思路
    冒泡算法由双层循环实现,其中外部循环用于控制排序轮数,一般为要排序的数组长度减1次,因为最后一次循环只剩下一个数组元素,不需要对比,同时数组已经完成排序了。而内部循环主要用于对比数组中每个相邻元素的大小,以确定是否交换位置,对比和交换次数随排序轮数而减少。
    在这里插入图片描述

#!/bin/bash
read -p "请输入一个数组列表:" list

arr=($list)                           #定义一个初始数组
echo "原数组的顺序为:${arr[@]}"

length=${#arr[@]}                     #获取数组的长度

#冒泡排序:
for ((i=1; i<$length; i++))           #定义比较轮数,为数组长度减1,并且要从1开始
do
	
	for ((j=0; j<$length-$i; j++))    #确定每次比较的元素下标,比较相邻2个元素,大的往后放,小的往前放,并且每轮比较的次数要随着轮数递减
	do
		first=${arr[$j]}              #获取第一个元素的值
		c=$[ j + 1 ]                 
		second=${arr[$c]}             #获取第二个元素的值
	
		 if [ $first -gt $second ]     #比较第一个元素和第二个元素的值,如果第一个元素的值大于第二个元素的值,则两个元素交换位置
		   then    
		     temp=$first                #先把第一个元素的值保存在临时变量temp中
	   	     arr[$j]=$second            #把第二个元素的值赋给第一个元素
		     arr[$c]=$temp              #把原来第一个元素的值赋给第二个元素 
	   	fi
	 done
done

echo "排序后新的数组的顺序为:${arr[@]}"

在这里插入图片描述
在这里插入图片描述

2、直接排序法

  • 与冒泡排序相比,直接选择排序的交换次数更少,所以速度更快

  • 基本思想

    将指定排序位置与其他数组元素分别对比,如果满足条件就交换元素值,注意这里区分冒泡排序,不是交换相邻元素,而是把满足条件的元素与指定的排序位置交换(如从最后一个元素开始排序),这样排序好的位置逐渐扩大,最后整个数组都成为已排序好的格式。

[root@localhost ~]# vim zhijie.sh
[root@localhost ~]# ./zhijie.sh
请输入一个数值列表:20 50 60 10 90
原始数组的顺序为:20 50 60 10 90
排序后的新数组的顺序为:10 20 50 60 90
[root@localhost ~]# vim zhijie.sh

#!/bin/bash
read -p "请输入一个数值列表:" list
arr=($list)
length=${#arr[@]}
echo "原始数组的顺序为:${arr[@]}"

#定义排序轮数
for ((i=1; i<$length; i++))
do
        #先假设最大的元素下标为0
        index=0
        #用于确定实际最大元素的下标,从第二个元素开始比较,最后一个元素的下标随着轮数递减
        for ((j=1; j<=$length-$i; j++))
        do
                if [ ${arr[$j]} -gt ${arr[$index]} ];then
                index=$j
                fi
        done
        #在确定好当前轮次的最大元素下标后,开始最大元素的值和当前轮次最后一个元素进行交换

        #获取每轮最后一个元素的索引
        last=$[$length - $i ]
        #把当前轮次的最后一个元素的值保存在临时变量中
        temp=${arr[$last]}
        #把最大的元素的值赋给最后一个元素
        arr[$last]=${arr[$index]}
        #把原最后一个元素的值赋给原最大值的位置的元素
        arr[$index]=$temp
done
echo "排序后的新数组的顺序为:${arr[@]}"

3、反转排序

  • 以相反的顺序把原有数组的内容重新排序

  • 基本思想

    把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,以此类推,直到把所有的数组元素反转替换。

#!/bin/bash

arr=(10 20 30 40 50 60 70)
length=${#arr[@]}

for ((i=0; i<length/2; i++))
do
        temp=${arr[$i]}
        arr[$i]=${arr[$length-$i-1]}
        arr[$length-$i-1]=$temp
done

echo ${arr[@]}

4、希尔排序

  • 希尔排序(Shell Sort)是插入排序的一种算法,是对直接插入排序的一个优化,也称缩小增量排序。

  • 原理
    希尔排序是将待排序的数组元素 按下标的一定增量分组 ,分成多个子序列,然后对各个子序列进行直接插入排序算法排序;然后依次缩减增量再进行排序,直到增量为1时,进行最后一次直接插入排序,排序结束。

  • 思路
    增量d 的范围: 1<= d < 待排序数组的长度 (d 需为 int 值)
    增量的取值:一般的初次取序列(数组)的一半为增量,以后每次减半,直到增量为1
    第一个增量=数组的长度/2
    第二个增量= 第一个增量/2
    第三个增量=第二个增量/2
    以此类推,最后一个增量=1

#!/bin/bash
array=(7 6 8 3 1 5 2 4)
length=${#array[*]}

#把距离为gap的元素编为一组,扫描所有的组,每次循环减少增量
for ((gap=$length/2; gap>0; gap/=2))
do
        for ((i=gap; i<$length; i++))
        do
        temp=${array[$i]}
        #对距离为gap的元素组进行排序,每一轮比较拿当前轮次最后一个元素与组内其他元素比较,将数组大的往后放
        for ((j=i-gap; j>=0&&temp<${array[$j]}; j-=gap))
        do
                array[$j+$gap]=${array[$j]}
        done
        #和左边较大的元素调换位置
        array[$j+$gap]=$temp
        done
done
echo ${array[*]}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Shell字符串数组是一种存储多个字符串的数据结构,可以通过下标访问数组中的元素,也可以通过循环遍历数组中的所有元素。在Shell脚本中,可以使用declare命令或者直接赋值的方式来创建字符串数组。例如,使用declare命令创建一个包含三个字符串的数组: declare -a arr=("hello" "world" "shell") 然后可以通过下标访问数组中的元素: echo ${arr[]} # 输出hello 也可以使用循环遍历数组中的所有元素: for i in "${arr[@]}" do echo $i done 输出结果为: hello world shell ### 回答2: Shell中的字符串数组是一种特殊的变量类型,用于存储多个字符串。在Shell脚本中,字符串数组可以用于存储一系列相关的字符串,并且可以对其进行遍历、操作和处理。 定义字符串数组可以使用以下语法: ``` array=("string1" "string2" "string3") ``` 其中,array是数组的名称,而"string1"、"string2"、"string3"是数组中的元素。 也可以逐个添加元素到数组中: ``` array[0]="string1" array[1]="string2" array[2]="string3" ``` 访问数组元素可以使用以下语法: ``` element=${array[index]} ``` 其中,index是数组中元素的索引,element是获取的数组元素。 对于数组的长度,可以使用以下语法: ``` length=${#array[@]} ``` 使用这个语法,可以获取数组中元素的个数。 遍历字符串数组可以使用循环语句: ``` for element in "${array[@]}" do echo $element done ``` 这个例子中,通过遍历${array[@]},我们可以访问数组中的每个元素,并将其打印出来。 使用字符串数组,可以方便地存储和处理一系列相关的字符串数据,从而实现更加灵活和高效的脚本编写。 ### 回答3: Shell字符串数组Shell编程语言中的一种数据结构,它可以存储多个字符串,并通过索引访问和操作。在Shell中,字符串数组可以通过以下方式定义和初始化: ```bash my_array=("string1" "string2" "string3") ``` 上述代码定义了一个名为my_array的字符串数组,其中有三个元素,分别是"string1"、"string2"和"string3"。我们可以通过数组索引来访问特定的元素,如: ```bash echo ${my_array[0]} # 输出第一个元素"string1" echo ${my_array[1]} # 输出第二个元素"string2" echo ${my_array[2]} # 输出第三个元素"string3" ``` 我们还可以通过下标的方式遍历整个数组,并对每个元素进行操作,如: ```bash for element in ${my_array[@]}; do echo $element done ``` 上述代码会将数组中的每个元素逐行输出。 在Shell中,我们可以使用数组来存储需要进行批量处理的数据,方便对多个字符串进行统一操作,比如切割、连接等。同时,字符串数组还可以作为函数的参数传递,方便将多个字符串作为一个整体进行处理。总的来说,Shell字符串数组是一种非常有用的数据结构,可以简化Shell脚本编写,提高代码的可读性和维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值