Shell编程:变量

mark

Shell变量

定义变量时,变量名不加美元符号$,如:

$ my_name="logos"

需要注意的是,变量名与等号之间不能有空格。同时变量命名遵循以下规则:

  • 只能使用英文字母,数字与下划线,首个字符不能以数字开头
  • 中间不能有空格,可以使用下划线
  • 不能使用标点符号
  • 不能使用bash里的关键字

使用变量

使用已经定义过的变量只需在变量名前加美元符号$即可

$ echo $my-name
$ echo $my_name
logos
$ echo ${my_name}
logos

变量名外面的花括号是可选的,加花括号是为了帮助解释器识别变量边界,因此推荐使用花括号。另已经定义过的变量可以重新被定义。

只读变量

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

$ my_name="logos"
$ readonly my_name
$ my_name="other"
zsh: read-only variable: my_name

删除变量

使用unset命令可以删除变量,但是无法删除只读变量

$ unset my_name

变量类型

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

  • 局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量
  • 环境变量:所有程序包括shell启动的程序都能访问环境变量
  • shell变量:由shell设置的特殊变量。shell变量中一部分是局部变量,一部分是环境变量。这些变量保证shell的正常运行

shell字符串

字符串是最常用的数据类型,可以用单引号、双引号,也可以不用引号。

单引号

$ str='This is a string'

单引号字符串的限制:

  • 单引号里的任意字符都会原样输出,单引号字符串中的变量是无效的
  • 单引号字符串中不能出现单引号,使用转义符也没用

双引号

$ my_name='logos'
$ str="Hello, I know you are \"${my_name}\"! \n"
$ echo ${str}
Hello, I know you are "logos"!

双引号的优点:

  • 双引号里面可以有变量
  • 双引号里可以出现转义符

拼接字符串

新建一个脚本string.sh

#!/bin/bash
my_name="logos"
greeting="hello, "$my_name" !"
greeting_1="hello, ${my_name} !"
echo $greeting $greeting_1

运行脚本

$ bash string.sh
hello, logos ! hello, logos !

获取字符串长度

$string="abcde"
$echo ${#string}
5

计算字符串长度也可以用length

$ expr length "$url"
26

字符串截取

字符串截取主要有4个截取符:###%%%:删除包含了指定的字符

  • #、##表示从左边开始截取,#表示从左边删除到指定的第一个字符;##表示从左边删除到最后一个指定的字符
  • %、%%表示从右边开始删除,%表示从右边删除到指定的第一个字符;%%表示从右边删除到最后一个指定的字符

linux的字符串截取有八种方法

假设我们有变量url=https://ytlogos.github.io/

#截取,删除左边字符,保留右边字符

$ echo ${url#*//}
ytlogos.github.io/

其中url是变量名,#是字符截取运算符,*//表示从左边开始删除第一个//及其左边所有字符,即删除https://

##截取,删除左边字符,保留右边字符

$ echo ${url##*/}

##*/表示从左边开始删除指定的最后一个字符/及其左边所有字符,所以上述结果就是空的。

%截取,删除右边字符,保留左边字符

$ echo ${url%/*}
https://ytlogos.github.io

%/*表示从右边开始删除第一个/及其右边字符

%%截取,删除右边字符,保留左边字符

$ echo ${url%%/*}
https:

%%表示从右边开始删除最后一个/及其右边的字符

从左边第几个字符开始及字符个数

$ echo ${url:0:5}
https

上述命令表示从左边第一个字符开始截取5个字符

从左边开始第几个字符开始一直到结束

$ echo ${url:5}
://ytlogos.github.io/

从右边第几个字符开始及字符个数

$ echo ${url:0-4:3}
.io

上述命令表示从右边第四个字符开始向右截取3个字符

从右边第几个字符开始一直到结束

$ echo ${url:0-7}
hub.io/

左边第一个字符用0表示,右边第一个字符用0-1表示

查找子字符串

查找字符g的位置

$ echo `expr index "$url" g`
13

如果字符串中不含那个字符的话,结果显示为0,另外如果查找多个字符的话只显示排在前面的字符

还有一点需要注意的是上面的是反引号`而不是单引号'

$ echo `expr index "$url" gt`
2

shell数组

bash支持一维数组(不支持多维数组),并且没有限定数组大小,数组元素下标从0开始,可以是整数或算术表达式。

定义数组

shell中数组的定义用括号表示,数组元素用空格分隔开。定义数组形式如下:

数组名=(值1 值2 ... 值n)

具体如下:

array_name=(v0 v1 v2 v3 v4 v5)

array_name=(
    v0
    v1
    v2
    v3
    v4
    v5
)

还可以通过赋值单独定义数组各个分量

array_name[0]=v0
array_name[1]=v1
.
.
.

可以不使用连续的下标,而且下标范围没有限制

数组读取

数组读取的一帮格式如下:

${数组名[下标]}
$ echo ${array_name[2]}
v1

使用@符号可以获取数组中所有元素

$ echo ${array_name[@]}
v0 v1 v2 v3 v4 v5

获取数组长度

获取数组长度的方法与获取字符串长度的方法相同:首先获取数组元素个数,再获取长度

$ echo ${#array_name[@]}
6
# 或
$ echo ${#array_name[*]}
6

shell注释

注释行都是以#开头,会被解释器忽略。不支持多行注释。

Researcher

I am a PhD student of Crop Genetics and Breeding at the Zhejiang University Crop Science Lab. My research interests covers a range of issues:Population Genetics Evolution and Ecotype Divergence Analysis of Oilseed Rape, Genome-wide Association Study (GWAS) of Agronomic Traits.

comments powered by Disqus