bash脚本编程之数组、高级字符串处理、高级变量操作、用户环境配置

概述:

    承接之前脚本编程部分,本篇将介绍一下脚本编程基础语法的最后一部分内容,具体分为:

        1、数组简介

        2、高级字符串处理

        3、高级变量操作

        4、用户环境配置

        5、数组实例演示

第一章    数组简介

    1、数组的相关概念

        数组:一种数据结构,存储多个元素的连续的内存空间,相当于多个变量的集合,可以使用索引获取相关元素

        数组名和索引

            索引:编号从0开始,属于数值索引

            注意:索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引, bash4.0版本之后开始支持。bash的数组支持稀疏格式(索引不连续)

    2、数组的定义

        declare -a ARRAY_NAME   声明为普通数组,可以不用事先定义,直接使用

        declare -A ARRAY_NAME   声明为关联数组,关联数组必须先申明后使用

    3、数组元素的赋值:

        <1>一次只赋值一个元素;ARRAY_NAME[INDEX]=VALUE

            weekdays[0]="Sunday"

            weekdays[4]="Thursday"

        <2> 一次赋值全部元素:(支持类似for中列表的赋值方式)

            ARRAY_NAME=("VAL1" "VAL2" "VAL3" …)

            如:

                aa=(/boot/*)

                aa=(`ls /root`)

                aa=({1..9})

                aa=({1,2}.{a,b})  此时数组中是1.a  1.b  2.a  2.b

            blob.png

        <3> 只赋值特定元素:ARRAY_NAME=([0]="VAL1" [3]="VAL2" …)

                如:color=(‘red’ ‘blue’ [6]=‘green’)

                此时color[0]值为red、color[1]值为blue、color[2]到color[5]值为空,color[6]值为green

        <4> 交互式数组值对赋值   read -a ARRAY_NAME

    4、数组引用

        引用数组中某元素的值: ${ARRAY_NAME[INDEX]}

            注意:省略[INDEX]表示引用下标为0的元素

        数组的长度(数组中元素的个数):

            ${#ARRAY_NAME[*]}

            ${#ARRAY_NAME[@]}

        数组的中某个元素的字符长度:

            ${#ARR_NAME[INDEX]}

        引用数组中的元素:

            所有元素: ${ARRAY[@]}, ${ARRAY[*]}

        数组切片: ${ARRAY[@]:offset:number}

            offset: 要跳过的元素个数

            number: 要取出的元素个数

        取偏移量之后的所有元素

            ${ARRAY[@]:offset}

        blob.png

    5、向数组中追加元素:(放到数组最后一个)

        ARRAY[${#ARRAY[*]}]

        blob.png

  

    6、删除数组中的某元素:导致稀疏格式

        unset ARRAY[INDEX]

        blob.png

    7、关联数组:declare -A ARRAY_NAME

        blob.png

第二章    高级字符串处理

    1、字符串切片:

        ${#var}:返回字符串变量var的长度

            如:

                aa=abcdefg

                echo ${#aa} 结果为7

        ${var:offset}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分,offset的取值在0 到 ${#var}-1 之间

            如:

                aa=abcdefg

                echo ${aa:3} 结果为defg

        ${var:offset:number}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分

            如:

                aa=abcdefg

                echo ${aa:3:2} 结果为de

        ${var: -lengh}:取字符串的最右侧几个字符:注意:冒号后必须有一空白字符

            如:

                aa=abcdefg

                echo ${aa: -3} 结果为efg

                echo ${aa:2: -1} 结果为 cdef

        blob.png

    2、基于模式取子串:

        ${var#*word}:其中word可以是指定的任意字符

        功能:自左而右,查找var变量所存储的字符串中,第一次出现的word, 删除字符串开头至第一次出现word字符之间的所有字符

            如:

                aa=abcdefgabcdefgabcdefg

                echo ${aa#*de} 结果为fgabcdefgabcdefg

        ${var##*word}:同上,不同的是,删除的是字符串开头至最后一次由word指定的字符之间的所有内容

            如:

                aa=abcdefgabcdefgabcdefg

                echo ${aa##*de} 结果为fg

            如:

                file="/var/log/messages"

                echo ${file##*/} 结果为 messages

        ${var%word*}:其中word可以是指定的任意字符;

        功能:自右而左,查找var变量所存储的字符串中,第一次出现的word, 删除字符串最后一个字符向左至第一次出现word字符之间的所有字符;

            如:

                aa=abcdefgabcdefgabcdefg

                echo ${aa%de*} 结果为 abcdefgabcdefgabc

            如:

                file="/var/log/messages"

                echo ${file%/*} 结果为 /var/log

        ${var%%word*}:同上,只不过删除字符串最右侧的字符向左至最后一次出现word字符之间的所有字符;

            如:

                aa=abcdefgabcdefgabcdefg

                echo ${aa%%de*} 结果为 abc

        blob.png

        blob.png

    3、查找替换:

        ${var/pattern/substi}:查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substi替换之

            如:

                aa=abcdefgabcdefgabcdefg

                echo ${aa/de/DE}  结果为 abcDEfgabcdefgabcdefg

        ${var//pattern/substi}: 查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substi替换之

            如:

                aa=abcdefgabcdefgabcdefg

                echo ${aa//de/DE}  结果为 abcDEfgabcDEfgabcDEfg

        ${var/#pattern/substi}:查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substi替换之

            如: 

                aa=abcdefgabcdefgabcdefg

                echo ${aa/#abcde/DE}  结果为 DEfgabcDEfgabcDEfg

        ${var/%pattern/substi}:查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substi替换之

            如: 

                aa=abcdefgabcdefgabcdefg

                echo ${aa/%efg/DE}  结果为 abcdefgabcdefgabcdDE

        blob.png

    4、查找并删除:

        ${var/pattern}:查找var所表示的字符串中,删除第一次被pattern所匹配到的字符串

            如: 

                aa=abcdefgabcdefgabcdefg

                echo ${aa/de}  结果为 abcfgabcdefgabcdefg

        ${var//pattern}:查找var所表示的字符串中,删除所有被pattern所匹配到的字符串

            如: 

                aa=abcdefgabcdefgabcdefg

                echo ${aa//de}  结果为 abcfgabcfgabcfg

        ${var/#pattern}:查找var所表示的字符串,删除行首所匹配到的字符串

            如: 

                aa=abcdefgabcdefgabcdefg

                echo ${aa/#abc}  结果为 defgabcdefgabcdefg

        ${var/%pattern}:查找var所表示的字符串,删除行尾所匹配到的字符串

            如: 

                aa=abcdefgabcdefgabcdefg

                echo ${aa/%efg}  结果为 abcdefgabcdefgabcd

        blob.png

    5、字符大小写转换:

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

            如: 

                aa=abCDEFGABcdEFGABCDefG

                echo ${aa^^}  结果为 ABCDEFGABCDEFGABCDEFG

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

            如:

                aa=abCDEFGABcdEFGABCDefG

                echo ${aa,,} 结果为 abcdefgabcdefgabcdefg

        blob.png

第三章    高级变量操作

    1、高级变量赋值:

        ${var:-value}

        功能:如果var为空或未设置,那么返回value,但是不会把值赋给var;否则,则返回var的值

            如:echo ${aa:-abcd}  结果为 abcd 此时 echo $aa  结果是空

                aa=1234;echo ${aa:-abcd} 结果为 1234

       blob.png 

        ${var:+value}

        功能:如果var不空,则返回value;也不会把值赋给var

            如:echo ${aa:+abcd} 结果为空

                aa=1234;echo ${aa:+abcd} 结果为 abcd

        blob.png

        ${var:=value}

        功能:如果var为空或未设置,那么返回value,并将value赋值给var;否则,则返回var的值

            如:echo ${aa:=abcd} 结果为 abcd 此时 echo $aa 结果为abcd

                aa=1234;echo ${aa:=bacd} 结果为 1234 此时 echo $aa 结果为1234

        blob.png

        ${var:?error_info}

        功能:如果var为空或未设置,那么返回error_info;否则,则返回var的值

            如: echo ${aa:?"cuo wu"} 结果为 -bash: aa: cuo wu

                此时echo $aa 结果为空

                aa=1234 ; echo ${aa:?"cuo wu"} 结果为 1234

        blob.png

    2、为脚本程序使用配置文件,实现变量赋值

        <1>定义文本文件,每行定义“ name=value”

        <2> 在脚本中source此文件即可

        blob.png

    3、间接变量引用:

        如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用

        variable1=variable2

        variable2=value

        variable1的值是variable2,而variable2又是变量名,variable2的值为value,间接变量引用是指通过variable1获得变量值value的行为

        间接变量引用的定义方式:

        方式一:eval VAR2=\$$VAR1

        方式二:VAR2=${!VAR1}

            如:

        blob.png

        blob.png

        eval命令:eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量。该命令对变量进行两次扫描

        blob.png

    4、利用declare命令,定义有型变量:

        Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令用于指定变量的类型,两个命令是完全等价的

        命令语法:declare [选项] 变量名

        常用选项:

            -r 将变量设置为只读属性

            -i 将变量定义为整型数

            -a 将变量定义为数组

            -A 将变量定义为关联数组,注意关联数组必须要先定义,后使用

            -f 显示此脚本前定义过的所有函数名及其内容

            -F 仅显示此脚本前定义过的所有函数名

            -x 将变量声明为环境变量

            -l 将变量值转为小写字母

            -u 将变量值转为大写字母

        blob.png

        blob.png    

        blob.png

    5、利用maketemp命令创建临时文件,可避免脚本中需要创建临时文件时造成的文件名冲突

        语法格式:mktemp [OPTION]… [TEMPLATE]

            TEMPLATE: filename.XXX    X至少要出现三个

            OPTION:

                -d: 创建临时目录

                –tmpdir=/DIR:指明临时文件所存放的目录位置,可以在创建的时候直接指定目录,而不利用–tempdir指定

            实例:

                mktemp –tmpdir=/testdir test.XXXXXX

                mktemp /testdir/file.XXX

        blob.png  

        blob.png

    6、bash展开命令行的优先级

        展开别名

        展开大括号种的声明{}

        展开波浪符声明~

        命令替换$() 和 “

        再次把命令行分成命令词

        展开文件通配 *、 ?、 [abc]等等

        准备I/0重导向<、 >

        运行命令

    7、防止扩展

        反斜线( \)会使随后的字符按原意解释

             echo Your cost: \$5.00

                Your cost: $5.00

        加引号来防止扩展

            单引号( ’)防止所有扩展

            双引号( ”)也防止所有扩展,但是以下情况例外:

                $(美元符号) - 变量扩展

                `(反引号) - 命令替换

                \(反斜线) - 禁止单个字符扩展

                !(叹号) - 历史命令替换

第四章    用户环境配置

    1、bash配置文件的分类

        按生效范围划分,存在两类:
            全局配置:
                /etc/profile
                /etc/profile.d/*.sh
                /etc/bashrc
            个人配置:
                ~/.bash_profile
                ~/.bashrc

    2、shell登录的两种方式和及其分别读取的配置文件

        交互式登录:
        <1>直接通过终端输入账号密码登录;
        <2>使用su – USERNAME 切换的用户
        配置文件执行顺序:
        /etc/profile –> /etc/profile.d/*.sh –>~/.bash_profile –> ~/.bashrc –> /etc/bashrc

        非交互式登录:
        <1>su USERNAME
        <2>图形界面下打开的终端
        <3>执行脚本
        配置文件执行顺序:
        ~/.bashrc –> /etc/bashrc –> /etc/profile.d/*.sh

    3、配置文件的作用

        按功能划分,存在两类:profiile类和bashrc类

        profile类:为交互式登录的shell提供配置
            全局: /etc/profile, /etc/profile.d/*.sh
            个人: ~/.bash_profile
            功用:
                <1> 用于定义环境变量
                <2> 运行命令或脚本

        bashrc类:为非交互式和交互式登录的shell提供配置
            全局: /etc/bashrc
            个人: ~/.bashrc
            功用:
                <1> 定义命令别名和函数
                <2> 定义本地变量

        修改profile和bashrc文件后需生效
            两种方法:
                <1>重新启动shell进程
                <2> . /PATH/TO/FILENAME 或source /PATH/TO/FILENAME
            例:
                .  ~/.bashrc

    4、退出登录的shell时执行任务的配置文件,保存在~/.bash_logout文件中

        用途:
            退出时自动创建备份
            退出时清除临时文件

第五章    数组实例演示

    1、输入若干个数值存入数组中,采用冒泡算法进行升序或降序排序

    #!/bin/bash    
    # Autor: nwc
    # Version: 2.0
    # CreateTime: 2016-08-23
    # Description: 
    
    read -p "input how much numbers you want to create: " NUM 
    
    if expr $NUM + 0 &>/dev/null && [ $NUM -ge 1 ] ; then
            for i in `seq 1 $NUM`;do
                    num[$i]=$RANDOM
            done
    else
            echo "bad input"
            exit 88
    fi
    
    echo -e "random numbers is:\n${num[@]}"
    
    n=${#num[@]}
    until [ $n -lt 1 ];do   
            for j in `seq 1 $n`;do
                    [ $j -lt $n ] && k=$[$j+1] || k=$n
                    if [ ${num[$j]} -gt ${num[$k]} ] ; then
                            mid=${num[$k]}
                            num[$k]=${num[$j]}
                            num[$j]=$mid
                    else
                            continue
                    fi
            done
            let n--
    done
    
    #正序从小到大排列
    echo "sort from small to large:"
    for m in `seq 1 ${#num[@]}`;do
            echo -ne "${num[$m]}\t"
    done
    echo
    
    #逆序从大到小排列
    echo "sort from large to small:"
    
    for r in `seq 1 ${#num[@]}|tac`;do
            echo -ne "${num[$r]}\t"
    done
    echo

    执行结果为:

    blob.png

原创文章,作者:M20-1倪文超,如若转载,请注明出处:http://www.178linux.com/39400

(0)
M20-1倪文超M20-1倪文超
上一篇 2016-08-23
下一篇 2016-08-24

相关推荐

  • ​Bash2

    字串比较时变量最好使用"" 这样就不会报错了,只是退出码不为0 组合条件:     与:[ condition1 -a condition2 ]或condition1 && condition2     或:[ condition1 -o co…

    Linux干货 2016-09-25
  • Nginx反向代理的常用调度算法

    upstream 调度算法 1.rr 按客户端请求顺序把客户端的请求逐一分配到不同的后端的服务器,这相当于lvs中的rr算法。如果后端服务器岩机(默认情况下只检测80端口,如果后端报502,404,403,503,还是会直接返给用户),岩机服务器会被自动剔除,使用户访问不受影响,请求会分配给正常的服务器 2.weight(权重) 在轮询算法的基础上加上权重(…

    Linux干货 2016-06-01
  • DNS服务器搭建从协议到实现详解

    一、域名和服务概述    1.FQDN:Fully Qualified Domain Name,完全限定域名,全局唯一           FQDN是指主机名加上全路径,全路径中列出了序列中所有域成员。全域名可以从逻辑上准确地表示…

    Linux干货 2016-04-30
  • 文件元数据信息详解

    文件元数据信息详解 文件的元数据是什么? 文件的数据分为两类:一类为数据,即文件的实际内容;另一类为元数据,用来描述文件的特征。 元数据内容: 文件名 文件大小 文件所在数据块 数据块的大小 文件类型 文件所在的Inode 硬链接次数 权限 属主id 属组id 最近一次访问时间戳 最近一次更改文件内容的时间戳 最近一次更改文件元数据的时间戳 查看文件的元数据…

    Linux干货 2017-07-09
  • 0811:脚本练习

    系统信息获取脚本 1、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。 [root@centos7 scripts]#cat systeminfo.sh  #!/usr/bin/bash  server_ip…

    Linux干货 2016-08-22
  • shell中if条件字符串、数字比对,[[ ]]和[ ]区别

    今天学习shell, if条件流程控制,但发现if[ ]]和if[ ]什么时候用不是清楚,正好看到一篇文章,非常好,转载,留个备份。 参考: http://www.51testing.com/?uid-7701-action-viewspace-itemid-13731 http://blog.csdn.net/sunboy_2050/article/det…

    Linux干货 2016-08-12