zoukankan      html  css  js  c++  java
  • Linux Shell脚本编程-数组和字符串处理

    数组
      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

  • 相关阅读:
    锐捷 ac ap 连接 记录
    锐捷 Fat/Fit Ap切换
    qualcomm lk gpio
    git patch 使用
    qualcomm batch 烧录脚本
    Cisco无线控制器配置Radius
    hostapd作为radius服务器
    Android N: jack server failed
    win10: This file can't be opened
    2. 特征工程之特征选择
  • 原文地址:https://www.cnblogs.com/Link-Luck/p/9855239.html
Copyright © 2011-2022 走看看