写点什么

OS 命令 --shell 中数组的操作

用户头像
cloudcoder
关注
发布于: 2021 年 03 月 01 日

在写程序的部署脚本或启动脚本时,经常用到 shell 中的数组操作,本文针对 shell 的数组操作进行总结 ,包括定义数组、读取数组、修改数组以及数组循环。

1. 数组介绍

shell 数组分为索引数组和关联数组,两者的最大的差别是:关联数组的元素是无序的、由特定格式的键值对组成、键是唯一的,同时使用键作为下标来索引关联数组元素。对于无变量类型的脚本语言,数字可以被看做特殊的字串。

  • 索引数组:即是普通的数组,通过数字下标引用

  • 关联数组:又称字典,是一种具有特殊索引方式的数组。不仅可以通过整数来索引它,还可以使用字符串或者其他类型的值(除了 NULL)来索引它

2. 数组操作

2.1 数据定义

#数组声明语法#定义索引数组declare -a arrayName#定义关联数组declare -A arrayName
#定义及初始化arrayName=() #定义一个空数组arrayName=(1 2 3 4 5) #全部元素为数字arrayName=(one two three four five) #全部元素为字符串
mydict=(["city"]="广州" ["addr"]="天河区体育东路120号" ["code"]=2222)
复制代码


示例脚本:

在部署一个分布式程序如海豚高度系统时,指定 worker 部署在多台服务器上,如配置为 workers="ds1:default,ds2:default,ds3:default,ds4:default,ds5:default",指定服务器及对应的分组,使用冒号分隔。脚本读取配置,使用如下:


# 定义部署worker的服务器列表workers="ds1:default,ds2:default,ds3:default,ds4:default,ds5:default"# 声明关联数组declare -A workersGroupMap=()# 将workers转换为索引数组workersGroup=(${workers//,/ })for workerGroup in ${workersGroup[@]}do  echo $workerGroup;  #获取worker及对应的分组名称  worker=`echo $workerGroup|awk -F':' '{print $1}'`  groupName=`echo $workerGroup|awk -F':' '{print $2}'`  #如果不存在,则直接添加,否则将worker对应的分组名称使用,拼接起来  if [ -z ${workersGroupMap[$worker]} ];then      workersGroupMap+=([$worker]=$groupName)  else      finalGroupName="${workersGroupMap[$worker]},$groupName"      workersGroupMap[$worker]=$finalGroupName  fidone
复制代码

2.1 数据引用

数组是一个变量,引用时也得使用 $符开头,但和普通标量变量不同,引用整个数组,需要使用 ${arrayName[*]}【注意:只对索引数组有效】或 ${arrayName[@]}形式,否则使用 $arrayName 或者 ${arrayName}只会得到第一个元素。同样,和标量变量一样,数组变量也可以进行长度、分片、替换等操作,如下:

 

  用下标读取某个元素的值

  arr_element=${arrayName[2]},即形式:${数组名[下标]}

针对关联数组,引用如下:

echo ${mydict['code']}

  用 #获取数组长度:${#数组名[@]} 或 ${#数组名[*]} 

  arr_len=${#arrayName[*]}或 ${#arrayName[@]}

 

       用 #获取某元素值的长度

  arr_len=${#arrayName[index]}   #index 为数组下标索引

 

  删除数组

    删除数组某个元素:unset arrayName[index]

    删除整个数组:unset arr_number

 

  数组分片访问

    分片访问形式为:${数组名[@或*]:开始下标:偏移长度}

    例如:

        arrayName=(1 2 3 test go now)

           echo ${arrayName[@]:1:2},将输出 2 3

    ${arrayName[@]:1:2},这里分片访问从下标 1 开始,元素个数为 2。


模式替换

  格式为:${数组名[@或*]/模式/新值}

  例如:echo ${arrayName[@]/now/past},将输出 1 2 3 test go past


2.3 数组循环

# 程序启动前,打印程序的每一个参数params=$@#程序启动入口startup(){  aparams=($params)  #echo "params len "${#aparams[@]}  len=${#aparams[@]}  for ((i=0;i<$len;i++));do    # 打印出每一个参数    echo "第${i}参数:${aparams[$i]}";     str=$str" "${aparams[$i]};  done  echo "Starting $APP_MAIN"  $JAVA_HOME/bin/java $JAVA_OPTS -classpath $CLASSPATH $APP_MAIN $str}startup
# 针对配置的IP,循环处理hostsArr=(${ips//,/ })for host in ${hostsArr[@]}do echo "$host complete"done
复制代码


发布于: 2021 年 03 月 01 日阅读数: 15
用户头像

cloudcoder

关注

10+IT行业老兵,熟悉大数据处理,分布式编程 2020.10.30 加入

InfoQ主页:https://www.infoq.cn/u/cloudcoder 头条主页: https://www.toutiao.com/c/user/token/MS4wLjABAAAAgqsp3gTUFRwr49uODP0W6XdaDB2vI5d_9yPDC1Nzmds/

评论

发布
暂无评论
OS命令--shell中数组的操作