在Shell脚本程序中,有时会使用数组,也就是具有相同数据类型的数据的集合。一般来说数组分为两类:索引数组和关联数组。下面请看示例:
1)arr_num=(1 2 3 4 5);
2)arr_string=("abcd" "uhfjs" "qwer")或arr_string=('abcd' 'uhfjs' 'qwer')
其中,1)为数值型数组,2)为字符串型数组;这些都是索引数组。arr_num[0]=1,arr_num[1]=2,.......;同样的,arr_string[0]=abcd,arr_string[1]=uhfjs,.......
在索引数组或关联数组中,数组的下标称之为键,对应的数组元素称之为值;索引数组中一个键只对应一个值,而关联数组一个键可以对应多个值。
定义数组的方式:方式1>见例1)和例2);方式2>arr_num[0]=1,arr_num[1]=2,......
打印特定索引的数组元素内容:echo ${arr_num[0]}....... index=5,echo ${arr_num[$index]}
以清单形式打印数组中所有元素:echo ${arr_num[*]}或echo ${arr_num[@]}
打印数组长度(数组内元素个数):echo ${#arr_num[*]}
特别地,当对一个数组中某个下标元素赋值时,有以下两种情况:第一,当某下标元素的值存在,新赋得值将直接覆盖原先的值;第二,若指定的下标超过了数组的长度,仍然会将元素的值插入数组中;
删除数组中的某个元素/清空数组中所有元素:unset arr_num[0] unset arr_num
数组切片:${ARRAY[@]:offset:number}
offset:要跳过的元素个数
number:要跳出的元素个数
取偏移量之后的所有元素:${ARRAY:offset}
向数组中追加元素:ARRAY[${#ARRAY[*]}]=value
定义关联数组:
declare -A ass_array
有两种方法为关联数组赋值,ass_array=([index1]=val1 [index2]=val2);ass_array[index1]=val1,ass_array[index2]=val2
列出关联数组的数组索引:echo ${!array_var[*]}或echo ${!array_var[@]}
关联数组是shell提供的,可使用任意字符串作为下标的数组,关联数组的下标和值称为键值对,他们是一一对应的关系,在关联数组中,键(下标)是唯一的,值可以不唯一
test.sh的文本内容如下:
name=(Tom Jim Lucy)
declare -A phone=([Tom]=135 [Jim]=131 [Lucy]=152)
for i in `eval echo {0..$((${#name[*]}-1))}`;do
echo "${name[i]} phone number is ${phone["$name[i]"]}"
done
执行脚本后,显示如下:
Tom phone number is 135
Jim phone number is 131
Lucy phone number is 152
取关联数组中的所有键:${!array[*]}或${!array[@]}
取关联数组中的所有值:${array[*]}或${array[@]}
取关联数组的长度:${#array[*]}或${array[@]}
与数组切片类似的,字符串的切片同样十分好用!
${#var}:取字符串变量var的长度
${var:offset}:取字符串变量var中从第offset个字符后(不包含第offset个字符串)的字符开始,到最后的部分,offset的值介于0和${#var}-1之间
${var:offset:number}:取var中从第offset个字符后(不包含第offset个字符串)的字符开始,长度为number的部分
${var: -length}:取var最右侧length个字符(冒号后一定要有空格)
${var:offset:-length}:从最左侧跳过offset字符,一直向右取到距离最右侧length个字符之间的部分
基于模式取子串
${var#*word}:其中word可以是指定的任意字符
功能:从左至右,查找var所存储的字符串中,第一次出现的word,删除字符串开头至第一次出现word字符之间所有字符。
${var##*word}:同上,贪婪模式,不同的是,删除的是字符串开头至最后一次由word指定的字符之间的所有内容
字符串的查找和替换
${var/pattern/substr}:查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substr替换之。
${var//pattern/substr}:查找var所表示的字符串中,所有被pattern所匹配到的字符串,以substr替换之。
${var/#pattern/substr}:查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substr替换之。
${var/%pattern/substr}:查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substr替换之。
字符串的查找及删除
${var/pattern}:删除var所表示的字符串中第一次被pattern所匹配到的字符串
${var//pattern}:删除var所表示的字符串中所有被pattern所匹配到的字符串
${var/#pattern}:删除var所表示的字符串中所有以pattern为行首所匹配到的字符串
${var/%pattern}:删除var所表示的字符串中所有以pattern为行尾所匹配到的字符串
字符串中字符的大小写转换
${var^^}:把var中的所有小写字母转换为大写
${var,,}:把var中的所有大写字母转换为小写
引申:shell下除sed命令外,提取文件名及文件路径的方法如下
一、使用变量操作符
${var##*/} (向右匹配,直到最后一个'/',将匹配到的内容删除,包括'/')
var=/dir1/dir2/file.txt
echo ${var##*/}
>>>file.txt
${var#*.}(向右匹配,直到第一个'.',将匹配到的内容删除,包括'.')
var=/dir1/dir2/file.tar.gz
echo ${var#*.}
>>>tar.gz
${var%/*}(向左匹配,直到第一个'/',将匹配到的内容删除,包括'/')
var=/dir1/dir2/file.txt
echo ${var%/*}
>>>/dir1/dir2
${var%%/*}(向左匹配,直到最后一个'/',将匹配到的内容删除,包括'/')
二、使用命令basename/dirname(专门用来文件名及路径)
var=/dir1/dir2/file.txt
echo $(basename ${var})
>>>file.txt
var=/dir1/dir2/file.txt
echo $(basename ${var} .txt)(注意{var}后面的空格)
>>>file
var=/dir1/dir2/file.txt
echo $(dirname ${var})
>>>/dir1/dir2