• Shell基础语法——变量、数组、字符串


    Shell 注释

    以 # 开头的行就是注释,会被解释器忽略。

    通过每一行加一个 # 号设置多行注释

    多行注释

    1. # 多行注释还可以使用以下格式:
    2. :<<EOF
    3. 注释内容...
    4. 注释内容...
    5. 注释内容...
    6. EOF
    7. # EOF 也可以使用其他符号:
    8. :<<'
    9. 注释内容...
    10. 注释内容...
    11. 注释内容...
    12. '
    13. :<
    14. 注释内容...
    15. 注释内容...
    16. 注释内容...
    17. !

    Shell 变量

    在 Bash shell 中,每一个变量的值都是字符串,无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储。当然,如果有必要,你也可以使用 Shell declare 关键字显式定义变量的类型,但在一般情况下没有这个需求,Shell 开发者在编写代码时自行注意值的类型即可。 

     变量名的命名规则:(注意,变量名和等号之间不能有空格

    • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
    • 中间不能有空格,可以使用下划线 _。
    • 不能使用标点符号。
    • 不能使用bash里的关键字(可用help命令查看保留关键字)。

    给变量赋值时,如果 value 不包含任何空白符(例如空格、Tab 缩进等),那么可以不使用引号;如果 value 包含了空白符,那么就必须使用引号包围起来。

    如果变量的内容是数字,那么可以不加引号;如果真的需要原样输出就加单引号;其他没有特别要求的字符串等最好都加上双引号,定义变量时加双引号是最常见的使用场景。

    使用变量

    使用一个定义过的变量,只要在变量名前面加美元符号即可。例:echo ${your_name}

     变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界

    将命令的结果赋值给变量

    Shell 支持将命令的执行结果赋值给变量,常见的有以下两种方式:

    1. variable=`command`
    2. variable=$(command)

    反引号和 $():

    1、两种变量替换的形式是等价的,可以随意使用;反引号和单引号非常相似,容易产生混淆,推荐使用$()。

    2、$() 支持嵌套,反引号不支持

    3、$() 仅在 Bash Shell 中有效,而反引号可在多种 Shell 中使用。

    只读变量

    使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

    删除变量

    使用 unset 命令可以删除变量。

    变量被删除后不能再次使用。unset 命令不能删除只读变量。

     

    变量类型

    运行shell时,会同时存在三种变量:

    • 1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
    • 2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
    • 3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

     Shell 字符串

    字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。

    下面我们说一下三种形式的区别:

    1) 由单引号' '包围的字符串:

    • 任何字符都会原样输出,在其中使用变量是无效的。
    • 字符串中不能出现单引号,即使对单引号进行转义也不行。但可成对出现,作为字符串拼接使用。

    2) 由双引号" "包围的字符串:

    • 如果其中包含了某个变量,那么该变量会被解析(得到该变量的值),而不是原样输出。
    • 字符串中可以出现双引号,只要它被转义了就行。

    3) 不被引号包围的字符串

    • 不被引号包围的字符串中出现变量时也会被解析,这一点和双引号" "包围的字符串一样。
    • 字符串中不能出现空格,否则空格后边的字符串会作为其他变量或者命令解析。

    拼接字符串

    在 Shell 中不需要使用任何运算符,将两个字符串并排放在一起就能实现拼接 

    1. #!/bin/bash
    2. name="Shell"
    3. url="http://c.biancheng.net/shell/"
    4. str1=$name$url #中间不能有空格
    5. str2="$name $url" #如果被双引号包围,那么中间可以有空格
    6. str3=$name": "$url #中间可以出现别的字符串
    7. str4="$name: $url" #这样写也可以
    8. str5="${name}Script: ${url}index.html" #这个时候需要给变量名加上大括号

    获取字符串长度

    ${#string_name},string_name 表示字符串名字。

    变量为数组时,${#string_name} 等价于 ${#string_name[0]}

    字符串的截取

    1、从指定位置开始截取

    这种方式需要两个参数:起始位置,截取长度

    1) 从字符串左边开始计数

    ${string: start :length}  可以length,截取到字符串末尾

    2) 从右边开始计数

    ${string: 0-start :length}

    同第 1) 种格式相比,第 2) 种格式仅仅多了0-,这是固定的写法,专门用来表示从字符串右边开始计数。

    这里需要强调两点:

    • 从左边开始计数时,起始数字是 0(这符合程序员思维);从右边开始计数时,起始数字是 1(这符合常人思维)。计数方向不同,起始数字也不同。
    • 不管从哪边开始计数,截取方向都是从左到右。

    2、从指定字符(子字符串)开始截取 

    这种截取方式无法指定字符串长度,只能从指定字符(子字符串)截取到字符串末尾。Shell 可以截取指定字符(子字符串)右边的所有字符,也可以截取左边的所有字符。 

    1) 使用 # 号截取右边字符

    ${string#*chars}

    其中,string 表示要截取的字符,chars 是指定的字符(或者子字符串),*是通配符的一种,表示任意长度的字符串。*chars连起来使用的意思是:忽略左边的所有字符,直到遇见 chars(chars 不会被截取)。

    2) 使用 % 截取左边字符

    ${string%chars*}

    请注意*的位置,因为要截取 chars 左边的字符,而忽略 chars 右边的字符,所以*应该位于 chars 的右侧。其他方面%#的用法相同。

    格式说明
    ${string: start :length}从 string 字符串的左边第 start 个字符开始,向右截取 length 个字符。
    ${string: start}从 string 字符串的左边第 start 个字符开始截取,直到最后。
    ${string: 0-start :length}从 string 字符串的右边第 start 个字符开始,向右截取 length 个字符。
    ${string: 0-start}从 string 字符串的右边第 start 个字符开始截取,直到最后。
    ${string#*chars}从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。
    ${string##*chars}从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。
    ${string%*chars}从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。
    ${string%%*chars}从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。

    查找子字符串

    查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):

    1. string="runoob is a great site"
    2. echo `expr index "$string" io`  # 输出 4

    注意: 以上脚本中 ` 是反引号,而不是单引号 ',不要看错了哦。

    Shell 数组

    Shell 没有限制数组的大小,理论上可以存放无限量的数据。

    Shell 数组元素的下标从 0 开始计数。
    获取数组中的元素要使用下标[ ],下标可以是一个整数,也可以是一个结果为整数的表达式;当然,下标必须大于等于 0。
    常用的 Bash Shell 只支持一维数组,不支持多维数组。 

    定义数组

    在 Shell 中,用括号来表示数组,数组元素用"空格"分割开。一般形式为:数组名=(值1 值2 ... 值n)

    注意,赋值号=两边不能有空格,必须紧挨着数组名和数组元素。

    Shell 是弱类型的,它并不要求所有数组元素的类型必须相同

    Shell 数组的长度不是固定的,定义之后还可以增加元素。

     

    只给特定元素赋值:ages=([3]=24 [5]=19 [10]=12)

    以上代码就只给第 3、5、10 个元素赋值,所以数组长度是 3。

    获取数组元素

    读取数组元素值的一般格式是:${数组名[下标]}

    使用@*可以获取数组中的所有元素,例如:

    1. ${nums[*]}
    2. ${nums[@]}
    3. # 两者都可以得到 nums 数组的所有元素。

    获取数组长度 

    利用@*,可以将数组扩展成列表,然后使用#来获取数组元素的个数,格式如下:

    ${#array_name[@]}
    ${#array_name[*]}

    1. # 取得数组元素的个数
    2. length=${#array_name[@]}
    3. length=${#array_name[*]}
    4. # 取得数组单个元素的长度
    5. lengthn=${#array_name[n]}
    6. #向数组中添加元素
    7. array_name[10]="添加元素"
    8. #删除数组元素
    9. unset array_name[1]

     数组拼接(数组合并)

    就是将两个数组连接成一个数组。拼接数组的思路是:先利用@*,将数组扩展成列表,然后再合并到一起。

    array_new=(${array1[@]}  ${array2[@]})
    array_new=(${array1[*]}  ${array2[*]}) 

    其中,array1 和 array2 是需要拼接的数组,array_new 是拼接后形成的新数组。

    删除数组元素(也可以删除整个数组)

    使用 unset 关键字来删除数组元素,具体格式:unset array_name[index]

    index 表示数组下标,如果不写下标,unset array_name 表是删除整个数组,所有元素都会消失。

    关联数组 

     Bash 支持关联数组,可以使用任意的字符串、或者整数作为下标来访问数组元素。

    关联数组使用 declare 命令来声明,语法格式:declare -A array_name

    -A 选项就是用于声明一个关联数组。

    关联数组的键是唯一的。

    1. #以下实例我们创建一个关联数组 site,并创建不同的键值:
    2. 实例1
    3. declare -A site=(["google"]="www.google.com" ["runoob"]="www.runoob.com" ["taobao"]="www.taobao.com")
    4. 实例2 我们也可以先声明一个关联数组,然后再设置键和值:
    5. declare -A site
    6. site["google"]="www.google.com"
    7. site["runoob"]="www.runoob.com"
    8. site["taobao"]="www.taobao.com"
    9. echo "数组的键为: ${!site[*]}"
    10. echo "数组的键为: ${!site[@]}"

    访问关联数组元素可以使用指定的键,格式如下:

    array_name["index"]

     在数组前加一个感叹号 ! 可以获取数组的所有键

    ${!site[*]}    ${!site[@]}

     

  • 相关阅读:
    Spring Start制作
    2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷9(私有云)
    JVM虚拟机知识点(保姆级教程)
    Baklib帮助中心:自助服务指南
    京东二面:Sychronized的锁升级过程是怎样的
    基于粒子群算法的无人机航迹规划-附代码
    Linux·内核-硬中断
    3、核心配置文件详解
    vue3 elementPlus 表格实现行列拖拽及列检索功能
    嵌入式PID算法总结
  • 原文地址:https://blog.csdn.net/weixin_47203903/article/details/128109402