• Shell编程中变量用法


    1. 变量替换

    语法 说明
    ${变量名#匹配规则} 从变量开头进行规则匹配,将符合最短的数据删除
    ${变量名##匹配规则} 从变量开头进行规则匹配,将符合最长的数据删除,贪婪匹配
    ${变量名%匹配规则} 从变量尾部进行规则匹配,将符合最短的数据删除
    ${变量名%%匹配规则} 从变量尾部进行规则匹配,将符合最长的数据删除,贪婪匹配
    ${变量名/旧字符串/新字符串} 将变量中的第一次出现的旧字符串替换成新字符串 【只替换第一次出现的旧字符串】
    ${变量名//旧字符串/新字符串} 将变量中的所有的旧字符串替换成新字符串 【全部的旧字符串进行替换】

    1.1 示例

    $ variable_1="I love you,Do you love me"
    $ echo $variable_1
    I love you,Do you love me
    $ var1=${variable_1#*ov}
    $ echo $var1
    e you,Do you love me
    $ var2=${variable_1##*ov}
    $ echo $var2
    e me
    # 从尾部进行查找,找到第一个即退出
    $ var3=${variable_1%ov*}
    $ echo $var3
    I love you,Do you l
    # 从尾部进行查找,贪婪模式,从尾部进行查找,找到最后一个
    $ var4=${variable_1%%ov*}
    $echo $var4
    I l
    # 变量替换
    $ echo $PATH
    /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
    # 只是替换第一个出现的地方
    $ var5=${PATH/bin/BIN}
    $ echo $var5
    /usr/local/BIN:/usr/bin:/bin:/usr/sbin:/sbin
    # 全部替换
    $ var6=${PATH//bin/BIN}
    $ echo $var6
    /usr/local/BIN:/usr/BIN:/BIN:/usr/sBIN:/sBIN
    

    2. 字符串处理

    2.1 计算字符串长度

    语法 说明
    方法一 ${#string} 字符串前面加上#,计算字符串的长度
    方法二 expr length "$string" 如果字符串string 有空格,则必须加上双引号
    # 示例 字符串长度
    $ var1="Hello World"
    $ len1=${#var1}
    $ len2=`expr length "${var1}" `
    

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

    语法 说明
    方法 expr index $string $substring 并不是获取子串的位置,实际获取的是字符的位置,位置从1开始
    # 示例 子串在字符串中的索引位置,实际是字符的位置
    $ var1="Hello World"
    $ idx=`expr index "${var1}" orld` # 这个获取到的位置,实际上是第一次出现o的位置,返回5
    

    2.3 计算子串长度

    语法 说明
    方法 expr match $string $substring 可以指定子串,子串必须从字符串的起始位置开始匹配
    # 示例 子串长度
    $ var1="Hello World"
    $ sub_len=`expr match "$var1" World` # 此时返回的是 0,子串必须从头开始匹配
    $ sub_len=`expr match "$var1" Hell` # 此时返回的是 4 
    $ sub_len=`expr match "$var1" Hell.*` # 此时返回的是 11 匹配的是整个字符串 . 任意字符 * 多个
    

    2.4 抽取子串

    语法 说明
    方法一 ${string:position} 从变量string中的position位置开始提取 ${string:0}提取所有的字符串
    方法二 ${string:position:length} 从position位置开始,匹配长度为 length
    方法三 ${string: -position} 冒号(:)后面必须有个空格,负号表示从尾部开始抽取 -1表示最后一位
    方法四 ${string:(position)} 如果position为正左边开始,为负从右边开始 同方法三
    方法五 expr substr $string $position $length 从position位置开始,匹配长度为 length
    $ var1="Hello World"
    $ sub1=${var1:2}
    $ echo $sub1
    llo World
    $ sub2=${var1:1}
    $ echo $sub2
    ello World
    $ sub2=${var1:0}
    $ echo $sub2
    Hello World
    $ sub2=${var1: 0}
    $ echo $sub2 
    Hello World
    $ sub2=${var1:(0)}
    $ echo $sub2
    Hello World
    $ sub2=${var1:(-1)}
    $ echo $sub2
    d
    $ sub2=${var1: -1}
    $ echo $sub2
    d
    $ sub2=${var1:0:5}
    $ echo $sub2
    Hello
    

    2.5 字符串分割

    cut基本语法:

    cut OPTION... [FILE]...
    

    选项:

    • -f : 通过指定哪一个字段进行提取。cut命令使用“TAB”作为默认的字段分隔符。
    • -d : “TAB”是默认的分隔符,使用此选项可以更改为其他的分隔符。
    • --complement : 此选项用于排除所指定的字段。
    • --output-delimiter : 更改输出内容的分隔符。

    下面的代码仅使用分隔符:打印/etc/passwd文件中每一行的第一个字段。

    $ cut -d ':' -f 1 /etc/passwd
    root
    bin
    daemon
    …
    # 下面的代码从/etc/passwd文件提取第一和第六个字段:
    $ grep '/bin/bash' /etc/passwd| cut -d ':' -f 1,6
    root:/root
    bob:/home/bob
    user01:/home/user01
    # 要显示字段的范围,请指定以-分隔的开始字段和结束字段,如下所示:
    $ grep '/bin/bash' /etc/passwd|cut -d ':' -f 1-4,6,7
    root:x:0:0:/root:/bin/bash
    bob:x:1000:1001:/home/bob:/bin/bash
    user01:x:1001:1002:/home/user01:/bin/bash
    # 排除所指定的字段
    # 在下面的代码中,打印所有字段,除了/etc/passwd文件中的第二个字段:
    $ grep '/bin/bash' /etc/passwd|cut -d ':' --complement -f 2
    root:0:0:root:/root:/bin/bash
    bob:1000:1001::/home/bob:/bin/bash
    user01:1001:1002::/home/user01:/bin/bash
    # **如何指定一个输出内容的分隔符**
    #要指定输出分隔符,请使用--output-delimiter选项。输入分隔符由-d选项指定,默认情况下#输出分隔符与输入分隔符相同。
    #先看一下没有使用--output-delimiter选项,是什么样子的:
    $ cut -d ':' -f1,7 /etc/passwd|sort
    adm:/sbin/nologin
    avahi:/sbin/nologin
    bin:/sbin/nologin
    bob:/bin/bash
    # 现在使用--output-delimiter选项,输出分隔符使用’ ‘空格分隔,看一下是什么样子的:
    $ cut -d ':' -f1,7 --output-delimiter=' ' /etc/passwd|sort
    adm /sbin/nologin
    avahi /sbin/nologin
    bin /sbin/nologin
    bob /bin/bash
    
    # cut命令的一个限制是它不支持指定多个字符作为分隔符。多个空格被视为多个字段分隔符,必须使用tr命令才能得到所需的输出
    # Demo 示例
    # 需求1. docker images 删除 包含 goharbor 所有的镜像
    $ docker images
    REPOSITORY                             TAG                         IMAGE ID       CREATED         SIZE
    goharbor/redis-photon                  v2.1.3                      161d45dcb2f5   2 months ago    68.9MB
    goharbor/harbor-registryctl            v2.1.3                      6c8f14771edd   2 months ago    132MB
    goharbor/registry-photon               v2.1.3                      51523bdfa59e   2 months ago    80.3MB
    goharbor/nginx-photon                  v2.1.3                      8f3f1df526c4   2 months ago    40.2MB
    goharbor/harbor-log                    v2.1.3                      d6143bc93728   2 months ago    106MB
    goharbor/harbor-jobservice             v2.1.3                      4940590a5dfb   2 months ago    169MB
    goharbor/harbor-core                   v2.1.3                      b9117e275f20   2 months ago    150MB
    goharbor/harbor-portal                 v2.1.3                      b76be38158a6   2 months ago    49.6MB
    goharbor/harbor-db                     v2.1.3                      7a8a8f4ca96d   2 months ago    172MB
    adoptopenjdk/openjdk8-openj9           alpine-slim                 440045c41637   2 months ago    142MB
    # 需要获取到第三列 的IMAGE ID,执行 docker rmi 进行删除
    # tr -s 替换重复的字符
    #  tr '	' ' ' 转换制表符为空格
    $ docker images | grep goharbor  | tr '	' ' ' | tr -s ' ' | cut -d' ' -f3
    161d45dcb2f5
    6c8f14771edd
    51523bdfa59e
    8f3f1df526c4
    d6143bc93728
    4940590a5dfb
    b9117e275f20
    b76be38158a6
    7a8a8f4ca96d
    # 删除镜像
    $ docker rmi $(docker images | grep goharbor  | tr '	' ' ' | tr -s ' ' | cut -d' ' -f3)
    
    # 需求2 获取全路径下的文件名,例如以下两个路径,以 / 分割后,数组的长度也不一样,数组的最后一个为文件名
    # /usr/local/gradle-6.8.3/lib/groovy-all-1.3-2.5.12.jar
    # /usr/local/gradle-6.8.3/README.md
    # rev 命令用于反向输出文件内容,即镜像输出,像镜子一样
    # 字符串反向后 分割后的第一个位置 就是文件名,但还是反向的,需要再次反向 rev
    $ dir_or_file=获取后全路径信息
    $ filename=`echo ${dir_or_file} | rev | cut -d'/' -f1 | rev`
    

    3. 命令替换

    命令替换有两种方式

    1. 使用 ` 符号包装命令

    2. 使用$(命令方式)

    # 方法1 `command`
    $ var1=`date "+%Y-%m-%d %H:%M:%S"`
    # 方法2 $(command)
    $ var1=$(date "+%Y-%m-%d %H:%M:%S")
    #示例 获取nginx进程的个数
    $ nginx_process_num=$(ps -ef | grep nginx | grep -v grep | wc -l)
    

    4. 有类型变量

    使用的命令有 declare 和 typeset

    declare 命令和typeset命令两者等价
    declare和typeset都是用来定义变量类型的

    • declare 命令参数表
      | 参数 | 含义, 如果要取消声明的变量,把 - 换成 + 即可 |
      | :--- | :-------------------------------------------- |
      | -r | 将变量设为只读, |
      | -i | 将变量设置为整数 |
      | -a | 将变量定义为数组 |
      | -f | 显示此脚本前定义过的所有函数及内容 |
      | -F | 仅显示此脚本前声明的函数名 |
      | -x | 将变量声明为环境变量,小写的x |
    # 只读变量
    $ declare -r var1="hell0"
    $ echo $var1
    hell0
    $ var1="aaa"
    bash: var1: readonly variable
    # 整型变量
    $ num1=10 # 默认定义的变量为字符串变量
    $ number=$num1+20 # 默认不会进行数学计算
    10+20
    # 需要需要进行数学计算,使用 expr
    $ expr $num1 + 10
    20
    # 使用decalre声明整型变量
    $ declare -i num3=50
    $ num3=$num1+90
    $ echo $num3
    100
    
    # 定义数组
    $ declare -a array
    $ array=("java" "python" "C" "C++") # 数组赋值,注意用空格进行分割,不是逗号
    $ echo ${array[0]} # 输出数组第一个位置上的值, 数组下标索引从0开始
    java
    $ echo ${#array[@]} # 输出数组中元素的个数
    4
    $ echo ${#array[1]} # 输出数组中索引下标为1位置的元素的长度
    6
    $ echo ${array[@]:1:3} # 输出数组中下标冲1位置开始到下标为3位置结束的元素
    python C C++
    $ echo ${array[@]/on/ON} # 将数组中所有的 on 替换成 ON
    java pythON C C++
    $ array[0]="go" # 将数组中的下标为0的索引位置上的值进行重新赋值
    $ echo ${array[@]}
    go python C C++
    $ unset array[0] # 删除数组下标为0的那个元素
    $  echo ${array[@]}
    python C C++
    $ unset array # 清空数组中的内容
    
    #定义环境变量
    $ declare -x num5 # 声明环境变量num5
    $ num5=90
    $ declare +x num5 # 取消声明的环境变量
    

    5. bash数学运算

    5.1 整数的运算

    语法, operator 也可以是比较大小的运算符
    方法一 expr $number1 operator $ number2
    方法二 $(($number1 operator $ number2)) ,尽量采用expr 进行数学运算
    ## 1.bash 数学运算之expr
    # | & < > * >= <= 等运算符需要进行转译, 如果为真 返回 1,否则返回0
    # 两个运算符之间必须都要有空格
    # $? 这个值代表命令的返回值
    expr $num1 | $num2  # num1 不为空且非0,返回num1; 否则返回num2
    expr $num1 & $num2  # num1 不为空且非0,返回num1; 否则返回0
    expr $num1 < $num2
    expr $num1 <= $num2
    expr $num1 > $num2
    expr $num1 >= $num2
    expr $num1 = $num2
    expr $num1 != $num2
    expr $num1 + $num2
    expr $num1 - $num2
    expr $num1 * $num2
    expr $num1 / $num2
    expr $num1 % $num2
    
    # 判断 num1 是整数
    expr $num + 1 &> /dev/null # 只有整数变量才能进行数学运算,浮点数不可以
    # 命令运算结果为 0 表示 可以进行数学运算  $? -eq 0
    

    5.2 浮点数运算

    bc是bash内建的运算符,支持浮点数运算
    内建变量scale可以设置,默认是0, 指定小数位数

    $ echo "23+45" | bc   
    68
    $ echo "23.2+45" | bc 
    68.2
    $ echo "23.2+45.65" | bc  
    68.85
    $ echo "23.2+45.657" | bc
    68.857
    $echo "23.2/5.657" | bc
    4
    $ echo "scale=4;23.2/5.657" | bc
    4.1011
    

    6.特殊变量

    shell编程中有一些特殊的变量可以使用。这些变量在脚本中可以作为全局变量来使用。

    名称 说明
    $0 脚本名称
    $1-9 脚本执行时的参数1到参数9
    $? 脚本的返回值
    $# 脚本执行时,输入的参数的个数
    $@ 输入的参数的具体内容(将输入的参数作为一个多个对象,即是所有参数的一个列表
    $* 输入的参数的具体内容(将输入的参数作为一个单词)

    $@与$*的区别:

      $@与$*都可以使用一个变量来来表示所有的参数内容,但这两个变量之间有一些不同之处。

      $@:将输入的参数作为一个列表对象

      $*:将输入的参数作为一个单词

  • 相关阅读:
    Hibernate 查询,返回结果设置到DTO
    sqlserver计算时间差DATEDIFF 函数
    SQL语句 不足位数补0
    Redis详细用法
    windows下安装Redis并部署成服务
    Redis命令
    ajax请求在参数中添加时间戳
    JS获取子节点、父节点和兄弟节点的方法实例总结
    js关闭当前页面清除session
    Java面试题一览
  • 原文地址:https://www.cnblogs.com/itgiser/p/14517740.html
Copyright © 2020-2023  润新知