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-24 10:12
下一篇 2016-08-24 10:12

相关推荐

  • 第二周-作业

    第二周作业: 题1、Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示。 Linux上常见的文件管理类命令有mkdir、touch、cp、mv、rm、stat。     mkdir:创建新目录         用法:mk…

    Linux干货 2016-12-08
  • CentOS7常用网络管理命令总结

    一、CentOS7网络接口命名策略(systemd)二、CentOS7的基础网络管理命令2.1 NetworkManager服务2.2 nmtui文本交互式工具2.3 nmcli命令行接口工具nmcli的语法说明NetworkManager整体状态显示显示所有连接或仅活动的连接显示所有设备的状态显示指定设备的所有连接属性添加动态的以太网连接(DHCP)添加静…

    Linux干货 2016-06-09
  • find查找命令及压缩

    文件查找     在文件系统上查找符合条件的文件;     文件查找: locate, find         非实时查找(数据库查找): locate    &nbs…

    Linux干货 2016-08-18
  • 马哥教育网络班22期第二周课程练习1-未闻花名

    1、Linux管理文件和目录的命令 命令 功能 命令 功能 pwd 显示当前目录 ls 查看目录下的内容 cd 改变所在目录 cat 显示文件的内容 grep 在文件中查找某字符 cp 复制文件 touch 创建文件 mv 移动文件 rm 删除文件 rmdir 删除目录 1.1 pwd命令 该命令的英文解释为print working directory(打…

    Linux干货 2016-08-29
  • Jerry的学习计划/目标/宣言

    学习计划 按照班主任给的计划进度来,多动手做实验。 目标 勇敢做自己,做更好的自己 宣言 能不能成为高富帅,日后是否能愉快地装逼,就看这半年!

    Linux干货 2016-10-24
  • Linux帮助文件的使用、history变量的使用和FHS

    怎样利用帮助文件来查询想要了解的信息? 这里以通过查找帮助文件来修改登陆信息为例子, 登陆的时候,我们可以看到CentOS的的版本和内核信息, 当我们查看该相关文件的时候,会发现,里面的文档和显示的不一致,由此可以了解到,该文档是调用某些参数来实现显示CentOS的版本和内核信息。 这个时候,我们该怎样去查看issue文档的相关信息? 首先我们可以查看一下通…

    Linux干货 2016-08-04