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

相关推荐

  • SED命令

    sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转…

    Linux干货 2017-05-01
  • 网络配置详解(一)

    Linux网络属性配置      ifcfg命令家族:ifconfig, route, netstat      ifconfig命令:      ifconfig [INTERFACE]      # ifconfig -a 显示所有接口…

    Linux干货 2017-01-02
  • 简单明了的Linux常用端口说明

    由于Linux常用端口很多,为了查看方便,所以特意整理了一些,详情如下        查看Linux常用端口   cat /etc/services # The Well Known Ports are those from 0 through 1023. 众所周知的端口是从0到1023。 # The Reg…

    Linux干货 2017-06-11
  • 加油吧!少年!—至我和我M25期的伙伴

    引用 衣带渐宽终不悔,为伊消得人憔悴。—王国维《人间词话》 转眼已到了27岁的年纪,不知道自己是否还称得上少年。公交上让座被小朋友成为叔叔也都是很多年的事了。哪怕再有一颗少年心现在也要肩负起整个家庭的责任。 从毕业已工作了将近六个年头,无聊的工作平凡的薪水已经使我厌倦。闭上眼睛以后需要赡养四个老人,还要照顾孩子以后这些难题映入脑海。曾经以为遥远的…

    Linux干货 2017-07-11
  • 位置变量&特殊变量总结

    位置变量 常用的位置变量有 $1, $2, $3 ……,表示命令行传给脚本的第一个参数,第二个参数,第三个参数。。。 $0 表示脚本的文件名,比如a.sh 位置变量在脚本中的主要作用,是让脚本通过他们来获取命令行传递给脚本的参数。 变量位置调整 shift [n] 用于调整变量位置 第n+1个位置变量会被重新命名为$1…

    Linux干货 2016-08-15
  • 发送mail的几种方法

    mail,顾名思义就是邮件。在这两天上课中,接触了发送mail的一些用法,课下自己在网上又查询补充了一下,总结出来,增加印像。 为了显示清晰,首先我们分别使用两个用户在不同的终端下登录,一个超级管理员root,一个是刚刚创建的用户zhangsan,看下图: 首先先来看一下发送mail用到什么选项:  -s<邮件主题>:指定邮件的主题; …

    2017-07-20