变量的高级用法

变量替换

语法 说明
\${变量名#匹配规则} 从变量开头进行匹配,将从第一个字符到第一次匹配到的字符为止的所有字符,全部删除。
\${变量名##匹配规则} 从变量开头进行匹配,将从第一个字符到最后一次匹配到的字符为止的所有字符,全部删除。
\${变量名%匹配规则} 从变量尾部向前进行匹配,将从最后一个字符到第一次匹配到的字符为止的所有字符,全部删除。
\${变量名%%匹配规则} 从变量尾部向前进行匹配,将从最后一个字符到最后一次匹配到的字符为止的所有字符,全部删除。
\${变量名/旧字符串/新字符串} 将从头开始的第一个旧字符替换成新字符
\${变量名//旧字符串/新字符串} 将所有旧字符替换成新字符

字符串的处理

计算字符串的长度

语法 说明
方法一 \${#string}
方法二 expr length "\$string" string如果有空格,则必须加双引号

获取子串在字符串中的索引位置

#语法
expr index "$string" substr

#该方法实际效果并不好,也不是类似java的完全匹配。
#从原理来讲,是将母串和子串都拆分成字符数组,并遍历母串的数组。如果母串的某个字符包含于子串数组中,则返回这个字符在母串中的位置。且数组下标是从1开始算起!

计算子串长度

#语法
expr match "$string" substr

#子串substr必须从头开始匹配。子串可以使用通配符

抽取子串

position指的是开始的下标

【注意】使用expr,索引是从1开始。使用\${string\:position}类方式,索引从0开始!

语法 说明
方法一 \${string\:position} 从string中的position开始到最后
方法二 \${string\:position\:length} 从position开始,匹配长度为length
方法三 \${string: -position} 从右边开始匹配
方法四 \${string:(position)} 从左边开始匹配
方法五 expr substr \$string \$position \$length 从position开始,匹配长度为length

字符串处理案例

需求:
    变量string="Bigdata process framework is Hadoop,Hadoop is an open source project"
    执行脚本后,打印输出string字符串变量,并给出用户以下选项:

    (1)、打印string长度
    (2)、删除字符串中所有的Hadoop
    (3)、替换第一个Hadoop为Mapreduce
    (4)、替换全部Hadoop为Mapreduce

    用户输入数字1|2|3|4,可以执行对应项的功能;输入q|Q则退出交互模式

代码

#!/bin/bash
#

string="Bigdata process framework is Hadoop,Hadoop is an open source project"

function print_tips
{
    echo "****************************"
    echo "(1)、打印string长度"
    echo "(2)、删除字符串中所有的Hadoop"
    echo "(3)、替换第一个Hadoop为Mapreduce"
    echo "(4)、替换全部Hadoop为Mapreduce"
    echo "***************************"
}

function len_of_string
{
    echo "${#string}"

}

function del_hadoop
{
    echo "${string//Hadoop/}"
}

function rep_hadoop_mapreduce_first
{
    echo "${string/Hadoop/Mapreduce}"
}

function rep_hadoop_mapreduce_all
{
    echo "${string//Hadoop/Mapreduce}"
}

while true
do
    echo "【string=$string】"
    echo
    print_tips
    read -p "Please input your choice(1|2|3|4|q|Q):" choice

    case $choice in
        1)
            len_of_string
            ;;
        2)
            del_hadoop
            ;;
        3)
            rep_hadoop_mapreduce_first
            ;;
        4)
            rep_hadoop_mapreduce_all
            ;;
        q|Q)
            exit
            ;;
        *)
            echo "Error,input only in {1|2|3|4|q|Q}"
            ;;

    esac
done

命令替换

格式

`command`
#或
$(command)

 ``和$()两者是等价的,但推荐初学者使用$(),易于掌握;缺点是极少数UNIX可能不支持,但``都是支持的

 $(())主要用来进行整数运算,包括加减乘除,引用变量前面可以加$,也可以不加$

案例

将passwd文件(用户信息)的第一个部分分隔出来并打印

#!/bin/bash
#

index=1
for user in $(cat /etc/passwd | cut -d ":" -f 1)
do

        echo "This is $index user: $user"
        index=$(($index+1))
done

与天数相关的案例

#!/bin/bash
#

echo "This year has passed $(date +%j) days"
echo "This year has passed $(($(date +%j)/7)) weeks"

echo "There is $((365-$(date +%j))) days before new year"
~                                                          

有类型变量

# shell中通过declare或typeset命令进行声明变量类型
# 两者完全等价

declare命令参数

参数 含义
-r 声明为只读
-i 声明为整数
-a 声明为数组
-f 显示此脚本前定义的所有函数及内容
-F 仅显示此脚本前定义过的函数名
-x 将声明变量为环境变量
declare -i num1

数组

declare -a array
array=("aaa" "bbb" "ccc" "ddd")
#定义数组的时候,以小括号包围,以空格分隔

#输出数组内容:                                            
    echo ${array[@]}    输出全部内容
    echo ${array[1]}    输出下标索引为1的内容
#获取数组长度:                                                        
    echo ${#array[@]}       数组内元素个数
    echo ${#array[2]}       数组内下标索引为2的元素长度
#给数组某个下标赋值:                                 
    array[0]="lily"               给数组下标索引为1的元素赋值为lily
    array[20]="hanmeimei"     在数组尾部添加一个新元素
#删除元素:                                              
    unset array[2]      清除元素
    unset array         清空整个数组
#分片访问:                                              
    ${array[@]:1:4}     显示数组下标索引从1开始到3的3个元素,不显示索引为4的元素
#内容替换:                                              
    ${array[@]/an/AN}   将数组中所有元素内包含an的子串替换为AN
#数组遍历:
    declare -a array
    array=("aaa" "bbb" "ccc" "ddd")
    for v in ${array[@]}
    do
        echo $v
    done

expr

语法格式

expr $num1 operator $num2
#或
$(($num1 operator $num2))

operator指操作符,可以是加减乘除,取余等,也可以是其他比较符号

操作符 含义
num1 | num2 num1不为空且非0,返回num1,否则返回num2
num1 & num2 num1不为空且非0,返回num1,否则返回0
num1 < num2 num1小于num2,返回1,否则返回0
num1 <= num2 num1小于等于num2,返回1,否则返回0
num1 = num2 num1等于num2,返回1,否则返回0
num1 != num2 num1不等于num2,返回1,否则返回0
num1 > num2 num大于num2,返回1,否则返回0
num1 >=num2 num1大于等于num2,返回1,否则返回0

需要注意,比较对象和运算符之间要有空格。命令行中,如“|”,“&”,“*”,“>”等运算符,需要加\进行转义

#判断一个变量是否是整数:和1相加,如果执行结果成功为整数,否则不是
num=1.1
expr $num + 1 &> /dev/null
echo $?

bc

简介

#bc是bash内奸的运算器,支持浮点数运算

#内建变量scale,指精确程度。可以设置, 默认为0

#bc有求指数操作 num1 ^ num2

#通过echo和管道,通过指令将算式传递给bc
echo "23+35" | bc

#通过分号,设置精度和求值、
echo "scale=2;5/2" | bc

函数

函数的定义和使用

函数的格式

#第一种格式
name()
{
    command1
    command2
    。。。。。。
    commandn
}

#第二种格式
function name 
{
    command1
    command2
    。。。。。。
    commandn
}

调用函数

#直接使用函数名调用,类似于使用一条命令
function_name 参数1 参数2 ...

#函数内部可以直接使用参数$1,$2,,,,,$n

向函数传递参数

函数返回值

局部变量和全局变量

函数库

shell编程的区别

如人饮水,冷暖自知。
最后更新于 2023-08-20