数组
  1、数组的定义及声明
  变量:存储单个元素的内存空间
  数组:存储多个元素的连续的内存空间,相当于多个变量的集合
  数组名:整个数组只有一个名字
  索引:编号从0开始,属于数值索引;bash的数组支持稀疏格式(索引不连续)
  格式:
    数组名[索引]
    ${ARRAY_NAME[INDEX]} 必需用花括号{ }
    注意:索引可支持使用自定义的索引格式,而不仅仅是数值格式,即为关联数组,bash4.0版本之后开始支持

  声明数组:
    declare -a ARRAY_NAME:声明一个索引数组
    declare -A ARRAY_NAME:声明一个关联数组(必须先声明再使用)

2、数组元素的赋值
  一次只赋值一个元素:
    格式:ARRAY_NAME[INDEX]=VALUE
    示例:
    weekdays[0]="Sunday"
    weekdays[4]="Thursday"

一次赋值全部元素:
    格式:ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...)
    注意:可以使用命令引用,glob通配等方法赋值

  一次只赋值特定元素:(支持稀疏格式的数组)
    格式:ARRAY_NAME=([0]="VAL1" [3]="VAL2" ...)

  使用read 交互式数组赋值:
    格式:read -a ARRAY

演示:
一次只赋值一个元素:
[root@centos7 ~]# declare -a animals #使用前最好先声明数组,当然不声明也可以
[root@centos7 ~]# animals[0]=pig
[root@centos7 ~]# animals[1]=dog

查看赋值,一定要注意书写格式,一定要加 {}
[root@centos7 ~]# echo $animals # 默认不加索引,显示第0个元素
pig
[root@centos7 ~]# echo $animals[0] # 错误写法,把其看做两部分 $animals 替换为 pig,[0]随后
pig[0]
[root@centos7 ~]# echo ${animals[0]}
pig
[root@centos7 ~]# echo ${animals[1]}
dog
[root@centos7 ~]# echo ${animals[*]} # 查看数组所有赋值
pig dog

一次赋值全部元素:
[root@centos7 ~]# number=(1 3 5 6 8 9)
[root@centos7 ~]# echo ${number[3]}
6
[root@centos7 ~]# echo ${number[0]}
1
[root@centos7 ~]# echo ${number[5]}
9
[root@centos7 ~]# echo ${number[*]}
1 3 5 6 8 9

# 下面的赋值方法也可以
[root@centos7 ~]# number=({1..9})
[root@centos7 ~]# echo ${number[*]}
1 2 3 4 5 6 7 8 9

[root@centos7 ~]# files=(/home/*)
[root@centos7 ~]# echo ${files[*]}
/home/centos /home/mage /home/mageedu

[root@centos7 ~]# files=($(ls /home)) # 命令引用 $()
[root@centos7 ~]# echo ${files[*]}
centos mage mageedu

[root@centos7 ~]# files=({1,2}{a,b}) # 命令行展开
[root@centos7 ~]# echo ${files[*]}
1a 1b 2a 2b

只赋值特定元素,稀疏格式的数组
[root@centos7 ~]# num=([0]=100 [2]=50 [3]=20)
[root@centos7 ~]# echo ${num[0]}
100
[root@centos7 ~]# echo ${num[2]}
50
[root@centos7 ~]# echo ${num[1]}

[root@centos7 ~]# echo ${num[3]}
20
[root@centos7 ~]# echo ${num[*]}
100 50 20

使用read交互式数组赋值
[root@centos7 ~]# read -a num
1 22 44 55 66 77 88 99
[root@centos7 ~]# echo ${num[0]}
1
[root@centos7 ~]# echo ${num[4]}
66
[root@centos7 ~]# echo ${num[6]}
88
[root@centos7 ~]# echo ${num[*]}
1 22 44 55 66 77 88 99

关联数组赋值
# 使用自定义的索引格式,即关联数组,如果不事先声明,会出现如下错误,索引总是显示最后一个元素
[root@centos7 ~]# username[F]=tao
[root@centos7 ~]# username[M]=xiu
[root@centos7 ~]# username[J]=jing
[root@centos7 ~]# echo ${username[F]}
jing
[root@centos7 ~]# echo ${username[M]}
jing
[root@centos7 ~]# echo ${username[J]}
jing
[root@centos7 ~]# echo ${username[*]}
jing

# 已经为索引数组就不能再次声明为关联数组了
[root@centos7 ~]# declare -A username
-bash: declare: username: 无法将索引数组转化为关联数组

# 声明一个关联数组,并赋值
[root@centos7 ~]# declare -A jianghu
[root@centos7 ~]# jianghu[A]=linghuchong
[root@centos7 ~]# jianghu[D]=qiaofeng
[root@centos7 ~]# jianghu[G]=yangguo

[root@centos7 ~]# echo "${jianghu[A]}"
linghuchong
[root@centos7 ~]# echo ${jianghu[D]}
qiaofeng
[root@centos7 ~]# echo ${jianghu[G]}
yangguo
[root@centos7 ~]# echo ${jianghu[*]}
linghuchong qiaofeng yangguo

3、引用数组元素
  引用数组中的元素:
  格式:${ARRAY_NAME[INDEX]}
  注意:省略[INDEX]表示引用下标为0的元素;
  索引数组是从0开始索引的,如果数组元素个数为n,那么索引数为 n-1

  数组的长度:(数组中元素的个数):
  格式:
   ${#ARRAY_NAME[*]}
    ${#ARRAY_NAME[@]}

  引用数组中的所有元素:
  格式:
    ${ARRAY_NAME[*]}
    ${ARRAY_NAME[@]}

  列出数组中的所有索引:
  格式:
   ${!ARRAY_NAME[*]}
   ${!ARRAY_NAME[@]}

演示:
[root@centos7 ~]# num=({1..9})
[root@centos7 ~]# echo ${#num[*]}
9

[root@centos7 ~]# echo ${num[*]}
1 2 3 4 5 6 7 8 9
[root@centos7 ~]# echo ${num[@]}
1 2 3 4 5 6 7 8 9

[root@centos7 ~]# var=(taotao jing xiu)
[root@centos7 ~]# echo ${#var[*]}
3
[root@centos7 ~]# echo ${var[*]}
taotao jing xiu

# {}里面是一个变量,${#VAR}就表示变量的长度,而之前的$#,表示传递给脚本的参数个数,注意区别
# 数组中单个元素的长度
[root@centos7 ~]# echo ${#var}
6
[root@centos7 ~]# echo ${#var[2]}
3
[root@centos7 ~]# echo ${#var[1]}
4

4、数组元素切片
  格式:${ARRAY_NAME[@]:offest:number}
  offest:要跳过的元素个数,即偏移量
  number:要取出的元素个数;省略number时,表示取偏移量之后的所有元素

演示:
[root@centos7 ~]# ls -d /etc/[Pp]*
/etc/pam.d /etc/php.d /etc/php.ini /etc/pki /etc/polkit-1 /etc/ppp /etc/profile /etc/pulse
/etc/passwd /etc/php-fpm.conf /etc/pinforc /etc/plymouth /etc/popt.d /etc/prelink.conf.d /etc/profile.d /etc/python
/etc/passwd- /etc/php-fpm.d /etc/pkcs11 /etc/pm /etc/postfix /etc/printcap /etc/protocols

# 一次赋值数组全部元素
[root@centos7 ~]# files=(/etc/[Pp]*)

[root@centos7 ~]# echo ${files[*]}
/etc/pam.d /etc/passwd /etc/passwd- /etc/php.d /etc/php-fpm.conf /etc/php-fpm.d
/etc/php.ini /etc/pinforc /etc/pkcs11 /etc/pki /etc/plymouth /etc/pm /etc/polkit-1
/etc/popt.d /etc/postfix /etc/ppp /etc/prelink.conf.d /etc/printcap /etc/profile
/etc/profile.d /etc/protocols /etc/pulse /etc/python

[root@centos7 ~]# echo ${#files[*]}
23

# 跳过前两个元素,取后面的三个元素
[root@centos7 ~]# echo ${files[@]:2:3}
/etc/passwd- /etc/php.d /etc/php-fpm.conf

# 跳过前20个元素,取后面的所有元素
[root@centos7 ~]# echo ${files[@]:20}
/etc/protocols /etc/pulse /etc/python

  5、数组的其它用法
  向非稀疏格式数组中追加元素(先通过${#ARRAY_NAME[*]}得到当前数组的长度,以长度数字作为索引号赋值)
  ARRAY_NAEM[${#ARRAY_NAME[*]}]=
  删除数组中的某元素
  unset ARRAY[INDEX]

  关联数组
    首先一定要声明数组(-A表示声明关联数组)
    declare -A ARRAY_NAME
    赋值
    ARRAY_NAME=([index_name1]="value1" [index_name2]="value2"...)

练习:生成10个随机数保存于数组中,并找出其最大值和最小值
[root@centos7 bin]# cat shuzu.sh
#!/bin/bash

declare -a rand
declare -i max=0
declare -i min=0

#思路:刚生成的第一个数同时赋值给最大和最小值,然后和后面生成的随机数作比较,如果大于最大值
# 就赋值给 max,如果小于 min 就赋值给 min

for i in {0..9};do
  rand[$i]=$RANDOM
  echo ${rand[$i]}
  if [ $i -eq 0 ];then
    max=${rand[$i]}
    min=${rand[$i]}
  elif [ ${rand[$i]} -gt $max ];then
    max=${rand[$i]}
  elif [ ${rand[$i]} -lt $min ];then
    min=${rand[$i]}
  fi
done

echo "MAX=$max"
echo "MIN=$min"

#==========================================================
[root@centos7 bin]# bash shuzu.sh
31054
4869
13722
9142
8027
16340
11938
10497
11232
13826
MAX=31054
MIN=4869

练习:写一个脚本,定义一个数组,数组中的元素是/var/log目录下所有以.log结尾的文件;要统计其下标为偶数的文件中的行数之和。
#!/bin/bash
#

declare -a files

files=(/var/log/*.log)

for i in $(seq 0 $[${#files[*]}-1]);do
  if [ $[$i%2] -eq 0 ];then
    lines=$(wc -l ${files[$i]} |cut -d" " -f1) # 取文件行数
    sumlines=$[$sumlines+$lines] # 总行数
  fi
done

echo "行数之和为:$sumlines"

bash的内置字符串处理工具
  字符串切片
  ${#var}        返回字符串变量var(是一个变量名)的长度
  ${var:offset}    返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分,offset的取值在0到${#var}-1 之间
  ${var:offset:number} 返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分
  ${var: -lengh}    取字符串的最右侧几个字符;注意:冒号后必须有一空白字符

演示:
[root@centos7 ~]# name=guojing
[root@centos7 ~]# echo ${name}
guojing

# 查看字符串变量的长度
[root@centos7 ~]# echo ${#name}
7

# 跳过指定的偏移量,取后面的所有字符
[root@centos7 ~]# echo ${name:2}
ojing
[root@centos7 ~]# echo ${name:3}
jing

# 跳过指定的偏移量,取指定长度的字符
[root@centos7 ~]# echo ${name:2:3}
oji
[root@centos7 ~]# echo ${name:3:3}
jin

#取字符串最右侧的指定长度字符
[root@centos7 ~]# echo ${name: -4}
jing
[root@centos7 ~]# echo ${name: -3}
ing

基于模式取子串
  ${var#*pattern}  查找var所表示的字符串中,删除自左而右第一次被pattern所匹配到的字符串及前面的所有字符串
  ${var##*pattern}  查找var所表示的字符串中,删除自左而右最后一次被pattern所匹配到的字符串及前面的所有字符串
  ${var%pattern*}  查找var所表示的字符串中,删除自右而左第一次被pattern所匹配到的字符串及后面的所有字符串
  ${var%%pattern*} 查找var所表示的字符串中,删除自右而左最后一次被pattern所匹配到的字符串及后面的所有字符串

演示:
[root@centos7 ~]# mypath="/etc/init.d/functions"

# 自左而右查找由word指定的任意字符,并删除
[root@centos7 ~]# echo ${mypath}
/etc/init.d/functions

[root@centos7 ~]# echo ${mypath#*/}
etc/init.d/functions

[root@centos7 ~]# echo ${mypath##*/}
functions

#==================================================================

# 自右而左查找由word指定的任意字符,并删除
[root@centos7 ~]# echo ${mypath%/*}
/etc/init.d

[root@centos7 ~]# echo ${mypath%%/*} # 因为最后一个为 路径首部的/所以全都删除了

[root@centos7 ~]# url=http://www.magedu.com:80

[root@centos7 ~]# echo ${url##*/} # 自左而右查找最后一次出现“/”的字符,并删除之间所有的
www.magedu.com:80

[root@centos7 ~]# echo ${url%%:*} # 自右而左查找最后一次出现“:”的字符,并删除之间所有的
http

[root@centos7 ~]# echo ${url##*:} # 自左而右查找最后一次出现“:”的字符,并删除之间所有的,实为取端口号
80

字符串查找替换
  ${var/pattern/substi}  查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substi替换
  ${var//pattern/substi} 查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substi替换
  ${var/#pattern/substi} 查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substi替换
  ${var/%pattern/substi} 查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substi替换
  注意:pattern中使用glob风格的通配符

演示:
[root@centos7 ~]# userinfo="root:x:0:0:root admin:/root:/bin/chroot"

[root@centos7 ~]# echo ${userinfo/root/ROOT}
ROOT:x:0:0:root admin:/root:/bin/chroot

[root@centos7 ~]# echo ${userinfo/r..t/ROOT} # 不支持使用正则表达式的模式匹配
root:x:0:0:root admin:/root:/bin/chroot

root@centos7 ~]# echo ${userinfo/r??t/ROOT} # 支持 glob 风格的模式匹配
ROOT:x:0:0:root admin:/root:/bin/chroot

[root@centos7 ~]# echo ${userinfo//root/ROOT} #查找所有能够被root匹配到的字符串,并替换为ROOT
ROOT:x:0:0:ROOT admin:/ROOT:/bin/chROOT

[root@centos7 ~]# echo ${userinfo//r??t/ROOT}
ROOT:x:0:0:ROOT admin:/ROOT:/bin/chROOT

[root@centos7 ~]# echo ${userinfo/#r??t/ROOT} # 查找行首能够被r??t匹配到的字符串,并替换为ROOT
ROOT:x:0:0:root admin:/root:/bin/chroot

[root@centos7 ~]# echo ${userinfo/%r??t/ROOT} # 查找行尾能够被r??t匹配到的字符串,并替换为ROOT
root:x:0:0:root admin:/root:/bin/chROOT

  字符串查找并删除
  ${var/pattern}  查找var所表示的字符串中,删除第一次被pattern所匹配到的字符串;
  ${var//pattern}  查找var所表示的字符串中,删除所有被pattern所匹配到的字符串;
  ${var/#pattern} 查找var所表示的字符串中,删除行首被pattern所匹配到的字符串;
  ${var/%pattern} 查找var所表示的字符串中,删除行尾被pattern所匹配到的字符串;

演示:
[root@centos7 ~]# echo ${userinfo}
root:x:0:0:root admin:/root:/bin/chroot

[root@centos7 ~]# echo ${userinfo/r??t} # 删除第一次被pattern所匹配到的字符串
:x:0:0:root admin:/root:/bin/chroot

[root@centos7 ~]# echo ${userinfo//r??t} # 删除所有被pattern所匹配到的字符串;
:x:0:0: admin:/:/bin/ch

[root@centos7 ~]# echo ${userinfo/#r??t} # 删除行首被pattern所匹配到的字符串;
:x:0:0:root admin:/root:/bin/chroot

[root@centos7 ~]# echo ${userinfo/%r??t} # 删除行尾被pattern所匹配到的字符串;
root:x:0:0:root admin:/root:/bin/ch

  字符大小写转换
  ${var^^}  把var中的所有小写字母转换为大写
  ${var,,}  把var中的所有大写字母转换为小写

演示:
[root@centos7 ~]# echo $url
http://www.magedu.com:80

[root@centos7 ~]# echo ${url^^} # 小写转换为大写
HTTP://WWW.MAGEDU.COM:80

[root@centos7 ~]# myurl=${url^^}

[root@centos7 ~]# echo $myurl
HTTP://WWW.MAGEDU.COM:80

[root@centos7 ~]# echo ${myurl,,} # 大写转换为小写
http://www.magedu.com:80

变量赋值
  ${varible:-default} 如果variable没有声明或者为空,则返回default字串;如果variable有值,则返回variable自身的值
  ${varible:+default} 如果variable没有声明或者为空,则返回空字串;如果variable有值,则返回default字串
  ${varible:=default} 如果variable没有声明或者为空,则返回default字串,并且将default赋值给variable;如果variable有值,则返回variable自身值
  ${varible:?default} 如果variable没有声明或者为空,则以default为错误信息返回;如果variable有值,则返回variable自身的值

变量测试与替换:用来判断x的值,y是否有值  

演示:
[root@centos7 ~]# echo $hi # 变量 hi 为空

[root@centos7 ~]# echo ${hi:-world} # 如果为空或未设置,那么返回word
world
[root@centos7 ~]# echo ${hi} # 但是并没有赋值给变量 hi

[root@centos7 ~]# hi=china # 现在赋值给变量 hi
[root@centos7 ~]# echo ${hi:-world} # 有值,则返回hi的变量值
china
[root@centos7 ~]# unset hi # 撤销变量
[root@centos7 ~]# echo ${hi}

#==========================================================
[root@centos7 ~]# echo ${hi:=world} #为空或未设置,那么返回world,并将world赋值给hi
world
[root@centos7 ~]# echo ${hi}
world

Linux Shell脚本编程-数组和字符串处理的更多相关文章

  1. Linux shell脚本编程(二)

    Linux shell脚本编程(二) 练习:求100以内所有偶数之和; 使用至少三种方法实现; 示例1: #!/bin/bash # declare -i sum=0 #声明一个变量求和,初始值为0 ...

  2. Linux shell脚本编程(一)

    Linux shell脚本编程: 守护进程,服务进程:启动?开机时自动启动: 交互式进程:shell应用程序 广义:GUI,CLI GUI: CLI: 词法分析:命令,选项,参数 内建命令: 外部命令 ...

  3. Linux shell脚本编程(三)

    Linux shell脚本编程 流程控制: 循环语句:for,while,until while循环: while CONDITION; do 循环体 done 进入条件:当CONDITION为“真” ...

  4. Linux Shell脚本编程--Linux特殊符号大全

    Linux Shell脚本编程--Linux特殊符号大全 linux_shell 特殊符号的介绍 2011

  5. Linux Shell脚本编程while语句

    Linux Shell脚本编程while语句案例 1,每隔3秒,打印一次系统负载 #!/bin/bash while truedo    uptime    sleep 3done 2,把监控结果保存 ...

  6. Linux Shell脚本编程-基础1

    概述:  shell脚本在Linux系统管理员的运维工作中非常重要.shell脚本能够帮助我们很方便的管理服务器,因为我们可以指定一个任务计划,定时的去执行某一个脚本以满足我们的需求.本篇将从编程基础 ...

  7. 【学习】Linux Shell脚本编程

    1.脚本的组成和执行 Linux shell脚本的结构并不复杂,其主要由变量.内部命令以及shell的语法结构和一些函数.其他命令行的程序等组成,以下是一个简单的shell脚本. #!/bin/bas ...

  8. [linux] shell脚本编程-xunsearch安装脚本学习

    安装脚本setup.sh #!/bin/sh # FULL fast install/upgrade script # See help message via `--help' # $Id$ # s ...

  9. Linux shell脚本编程基础之练习篇

    shell脚本编程基础之练习篇. 1.编写一个脚本使我们在写一个脚本时自动生成”#!/bin/bash”这一行和注释信息. #!/bin/bash ] then echo "请输入一个参数& ...

随机推荐

  1. 【网络协议】ICMP协议、Ping、Traceroute

        ICMP协议 ICMP常常被觉得是IP层的一个组成部分,它是网络层的一个协议.它传递差错报文以及其它须要注意的信息.ICMP报文通常被IP层或更高层(TCP.UDP等)使用,它是在IP数据报内 ...

  2. SpringMVC 拦截器不拦截静态资源的三种处理方式方法

    方案一.拦截器中增加针对静态资源不进行过滤(涉及spring-mvc.xml) <mvc:resources location="/" mapping="/**/* ...

  3. c15--二位数组

    // // main.c // day08 #include <stdio.h> int main(int argc, const char * argv[]) { /* int scor ...

  4. 自然语言处理(NLP)书籍资源清单

    1. 书籍 入门: <Speech and Language Processing>Dan Jurafsky ,James H. Martin 2. blog及项目

  5. Tool-Java:Eclipse

    ylbtech-Tool-Java:Eclipse Eclipse 是一个开放源代码的.基于Java的可扩展开发平台.就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境.幸运的是,E ...

  6. 南海区行政审批管理系统接口规范v0.3(规划) 2.业务申报API 2.1.businessApply【业务申报】

    {"v_interface":"2015987654327","c_project":"NH09A102"," ...

  7. 大数据学习之路------借助HDP SANDBOX开始学习

    一开始... 一开始知道大数据这个概念的时候,只是感觉很高大上,引起了我的兴趣.当时也不知道,这个东西是做什么的,有什么用,当然现在看来也是很模糊的样子,但是的确比一开始强了不少. 所以学习的过程可能 ...

  8. NOIP2013 D2T1 积木大赛

    [NOIP2013T4]积木大赛 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 noip2013day2 描述 春春幼儿园举办了一年一度的"积木大 ...

  9. POJ 2492 A Bug's Life 带权并查集

    题意: 思路: mod2 意义下的带权并查集 如果两只虫子是异性恋,它们的距离应该是1. 如果两只虫子相恋且距离为零,则它们是同性恋. (出题人好猥琐啊) 注意: 不能输入一半就break出来.... ...

  10. 用Navicat自动备份mysql数据库

    以下文章转载自https://blog.csdn.net/u013628152/article/details/54909885,放在自己的博客园以供后面方便查询 —————————————————— ...