shell中条件判断
shell脚本if判断变量介绍
变量 含义
[ -a FILE ] 如果 FILE 存在则为真
[ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真
[ -c FILE ] 如果 FILE 存在且是一个字符特殊文件则为真
[ -e FILE 如果 FILE 存在则为真
[ -f FILE ] 如果 FILE 存在且是一个普通文件则为真
[ -g FILE ] 如果 FILE 存在且已经设置了SGID则为真
[ -h FILE ] 如果 FILE 存在且是一个符号连接则为真
[ -k FILE ] 如果 FILE 存在且已经设置了粘制位则为真
[ -r FILE ] 如果 FILE 存在且是可读的则为真
[ -s FILE ] 如果 FILE 存在且大小不为0则为真
[ -t FD ] 如果文件描述符 FD 打开且指向一个终端则为真
[ -u FILE ] 如果 FILE 存在且设置了SUID (set user ID)则为真
[ -w FILE ] 如果 FILE 如果 FILE 存在且是可写的则为真
[ -x FILE ] 如果 FILE 存在且是可执行的则为真
[ -O FILE ] 如果 FILE 存在且属有效用户ID则为真
[ - G FILE ] 如果 FILE 存在且属有效用户组则为真
[ -L FILE ] 如果 FILE 存在且是一个符号连接则为真
[ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则为真
[ -S FILE ] 如果 FILE 存在且是一个套接字则为真
[ -z STRING ] “STRING” 的长度为零则为真
字符串判断
变量 含义
str1 = str2 两个字符串完全相等为真
str1 != str2 两个字符串不完全相等为真
-n str1 当串的长度大于0时为真(串非空)
-z str1 当串的长度为0时为真(空串)
str1 当串str1为非空时为真
数字判断
变量 含义
int1 -eq int2 两数字相等为真
int1 -ne int2 两数字不相等为真
int1 -gt int2 int1大于int2为真
int1 -ge int2 int1>= int2为真
in1 -lt int2 int1<int2 为真
int1 -le int2 int1 <= int2为真
文件判断
变量名 含义
-r file 用户可读为真
-w file 用户可写为真
-f file -文件为正规文件为真
-x file 用户可执行为真
-d file 文件为目录为真
-c file 存在且是特殊字符文件为真
-s file 文件大小非0为真
-b file 文件为块特殊文件为真
-t file 文件描述符(默认1)指定的设备为终端时为真
复杂逻辑
变量名 含义
-a 与
-o 或
! 非
!= 不等于
shell中特殊字符
特殊字符 | 功能 | 说明 | 注意 |
---|---|---|---|
# | 1.注释 2.声明命令解释器的类型 3.某些特定的模式匹配操作使用 | 1.注释方面:一般是行首中以 #作为开头 2.声明解释器类型一般是在脚本第一行。使用格式:#!/bin/bash | 命令不能和注释在同一行上,也就是注释的后面 |
; | 命令分隔符,可以在同一行上写多个命令 | 某些情况需要使用转义符转义 | |
;; | 双分号,终止case选项 | ||
. | bash内置命令 | 1.点(.)放在文件名前面表示隐藏文件。 2.移动文件操作时,如果是单独点作为参数cp cxx/helloworld.sh .表示当前工作目录 3.两个点(…),表示上一级目录。 4.正则表达式中作为匹配任何的单个字符 | |
" " | 双引号表示字符串 | ||
’ ’ | 单引号表示字符 | ||
, | 逗号操作符 | 链接一系列操作 | |
\ | 反斜杠() | 对单个字符的引用机制 | 一般用来转义双引号(" ") 和单引号(’ ')。 |
/ | 正斜杠(/) | 1.作为文件名路径分隔符/data/cxx/Makefile 2.用作除法算术操作符 | |
* | 1.乘法算术操作符 2.两个(**)表示求幂运算符 3.通配符,可以用来匹配给定目录下的任何文件名 | ||
? | 1.测试通配符 2.通配符,在正则表达式中表示一个字符,也可以用来匹配单个字符。 | 在表达式中测试一个条件的结果,类似C语言中的三元操作符。 | |
$ | 1.引用变量 2.正则表达式中,表示行结束符。 | ||
${} | 参数替换 | ||
$* or $@ | 位置参数 | ||
$$ | 进程ID变量 | 保存所在脚本的进程ID | |
$? | 退出状态码变量 | 可保存命令、函数或者脚本本身的退出状态码 | 一般是0或 1。 |
{ } | 大括号,代码块,也叫作内部组。 | 在函数或者判断语句中使用代码块 | 在大括号中不允许有空白,除非空白被引用或者转义 |
[ ] | 1.测试条件 2.数组元素 3.字符范围 | 作为字符范围时,方括号描述一个匹配的字符范围 | |
> &> >& >> < <> | 重定向 |
转义字符
转义符是一种引用单个字符的方法。添加转义符(\)
使得shell中的某个字符失去原有特殊含义。
注意:在echo
和 sed
中谨慎使用转义符,否则会有相反效果。
转义符 | 含义 | 实例 |
---|---|---|
\n | 表示新的一行 | echo “first line”;echo $‘\n’;echo “third line” |
\r | 表示回车 | |
\t | 表示水平制表符 | |
\v | 表示垂直制表符 | |
\b | 表示后退符 | |
\a | 表示"alert" (蜂鸣器或闪烁) | |
\0xx | 转换为八进制的ASCII码,等价于0xx | |
\" | 表示双引号 | |
\$ | 表示$本身的意思,跟在后面的变量名不会起作用 | echo “\$variables~~~~” |
\ | 表示反斜线 | echo “\\” #结果为 \ |
赋值给变量的字符串的元素也会被转义, 但是不能把一个单独的转义符赋值给变量。
shell中参数
字符符号 | 功能(用途) |
---|---|
$0 | shell文件本身的文件名 |
1 ~ 1~ 1~n | 添加到Shell的各参数值。$1是第1参数、 2 是第 2 参数、 … 、 2是第2参数、…、 2是第2参数、…、n表示第n个参数。⚠️注意:10以上要用大括号,如{10}。 |
$? | 最后运行命令的结束代码(返回值),执行成功返回0,不成功则返回非零值(一般解释为错误码)。 |
$$ | Shell本身的PID(ProcessID) |
$! | Shell最后运行的后台Process的PID |
$- | 使用Set命令设定的Flag一览 |
$* | 所有参数列表。如 “$*“用「”」括起来的情况、以”$1 $2 … $n" 的形式输出所有参数。 |
$@ | 所有参数列表。如 “$@“用「”」括起来的情况、以”$1" “ 2 " … " 2" … " 2"…"n” 的形式输出所有参数。 |
$# | 添加到Shell的参数个数 |
$\*
和 $#
的区别:
- 不被双引号包含时,两者没有区别。
- 当被
双引号包含
时,$*
是将所有参数
看作一整个数据
。而$#
则是将每个参数
看作一个数据
。
具体实例脚本:
#!/bin/bash
# 已进行shellcheck检查
echo "This is \$0 ---- : $0"
echo "This is \$1 ---- : $1"
echo "This is \$2 ---- : $2"
echo "This is \$? ---- : $?"
echo "This is \$$ ---- : $$"
echo "This is \$! ---- : $!"
echo "This is \$_ ---- : $_"
echo "This is \$* ---- : $*"
echo "This is \$@ ---- : $*@"
echo "This is \$# ---- : $#"
变量
变量表示数据的方法。是计算机为了保存数据项而在内存中分配的一个位置或一组位置的标识或名字。
变量名就是保存值的地方
。
shell变量有系统变量和自定义变量两种。
对于变量名的声明规则类似于其他编程语言。由字母、数字、下划线组成,但不能以数字开头。
hello_123 # 合法
123_hello # 不合法
内部变量
主要记录实际工作中使用的,也不要记住。用到了再查即可。
系统变量 | 说明 | 实操 | 备注 |
---|---|---|---|
$BASH_VERSION | 查看bash的版本 | echo $BASH_VERSION | |
$BASH | bash的二进制程序文件的路径 | echo $BASH | |
$USER | 当前用户 | echo $USER | 一般是root |
$EUID | 有效用户ID | echo $EUID | E U I D 不一定与 EUID 不一定与 EUID不一定与UID相同 |
$FUNCTION | 在函数中,可直接打印当前函数的名字 | ||
$GROUP | 当前用户所属的组 | echo $GROUP | 一个组ID列表 |
$HOSTNAME | 当前主机名字 | echo $HOSTNAME | |
$HOSTTYPE | 当前主机类型 | echo $HOSTTYPE | |
$PATH | 可执行文件的搜索路径 | echo $PATH | 以冒号分隔的目录列表 |
pwd | 当前工作目录 | pwd |
自定义变量基本语法
-
定义变量:
变量名=变量值
,等号两侧不能有空格(与其它语言可设空格的区别之处)。变量名一般习惯使用大写。 -
设置变量:
set 变量名=变量值
。 -
删除变量:
unset 变量名=变量值
。 -
声明静态变量:readonly 变量名,静态变量不能用unset
-
使用变量:$变量名
-
变量赋值
-
-
简单赋值:a=123 && echo $a
-
命令行赋值给变量*
#使用反引号* str=`cat helloworld.sh`
*#直接使用 ( . . ) 格式 ∗ o s = (..)格式* os= (..)格式∗os=(cat /etc/os-release)
-
-
局部变量:只在代码块或函数中可见可用。外部不可用。
-
Bash变量:不区分类型,都是字符串,不允许进行数值计算,除非变量中包含数字。
-
如果变量的值
中间有空格
,则使用引号(单引号或双引号均可)
扩起来。
环境变量
会影响用户接口和shell的行为。环境变量是一个全局变量。
通过 export 命令将变量声明为环境变量即可。
export 变量名=变量值
# 方式 1 :直接export导入,命令行窗口重启后失效
export LD_LIBRARY_PATH=/usr/local/cuda/lib
# 方式 2
# 加入到 root目录下的 .bashrc 中
# 使用 source ./bashrc 使修改后的配置信息生效,命令行窗口重启或者机器重启均不会失效
# 查看环境变量是否生效
echo $变量名
echo $LD_LIBRARY_PATH
对于环境变量的查看
# 方式 1 :查看所有变量(包括环境变量和自定义变量)
set
# 方式 2 :只能查看环境变量
env
引用变量
引用:将字符串使用双引号扩起来。作用:保护字符串的特殊字符(通配符)不被shell重新解释或者扩展。
[root@centos8 data]# var01=3
[root@centos8 data]# echo $var01
3
在引用变量时,需要使用$
来进行引用变量的值。
变量在使用过程中,如果没有$
作为前缀,需要思考如下情况:
-
被声明或被赋值。
-
是否被
unset
-
被使用
export
方式导入 -
是否作为信号量。
-
赋值的两种方式:
-
- 使用
=
方式。 - 直接使用
read
命令。
- 使用
运算符
运算符 | 描述 | 备注 |
---|---|---|
+ | 加法 | 延伸 += |
- | 减法 | 延伸 -= |
* | 乘法 | 延伸 *= |
** | 求幂 | |
/ | 除法 | 延伸 /= |
% | 求模(余数) | 延伸 %= |
++ | 自增 | a++ 等于 a = a + 1 |
– | 自减 | a-- 等于 a = a - 1 |
运算符 | 英文全称 | 中文描述 | 示例 |
---|---|---|---|
-eq | equal | 等于 | [ 1 -eq 1 ]为 true |
-ne | not equal | 不等于 | [ 1 -ne 1 ]为 false |
-gt | greater than | 大于 | [ 2 -gt 1 ]为 true |
-lt | lesser than | 小于 | [ 2 -lt 1 ]为 false |
-ge | greater or equal | 大于或等于 | [ 2 -ge 1 ]为 tbnrue |
-le | lesser or equal | 小于或等于 | [ 2 -le 1 ]为 false |
运算符 | 描述 | 等价使用 | 具体说明 |
---|---|---|---|
&& | 逻辑与(AND) | -a | 需两个为True |
|| | 逻辑或(OR) | -o | 其中之一为True |
字符串
字符串是由单引号('')
或者 双引号("")
或者也可不用引号。
-
单引号
-
- 原样输出(变量依然原样输出)
- 单引号内不能再使用单引号。
-
双引号
-
- 如果其中使用了变量,则变量内容也会被替换。
- 如果再次使用引号,则使用转义符。
-
不用引号
-
- 性质和双引号一致,但是字符串不能有空格。
字符串长度
直接使用 ${#string}
来计算字符串的长度
# 3 个语法格式
${#string} # 方式 1
expr length $string # 方式 2
expr "$string" : '.*' # 方式 3
# 具体实例
str="hello world"
echo "After using #str : ${#str}"
echo "Use expr length : $(expr length "$str")" # 该方式不建议使用,因为shellcheck也建议使用第一种方式
echo "Use expr : $(expr "$str" : '.*')"
索引子串第一次出现的位置
# 语法格式 :
expr index "$string" '$substring'
# 详细实例 ---- 未进行shellcheck检查
str="SolerHO123456"
echo $(expr index "$str" H) # 结果为 6
提取字串
目的:提取一些特殊需求的字符。
语法 | 说明 |
---|---|
${string:position} | 在string中从位置position开始提取子串 |
${string:position:length} | 在string中从位置position开始提取 length长度的字串 |
子串截除
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mWOG3xCu-1658150017451)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20220529204521267.png)]
子串替换
数组
bash支持只支持一维数组。数组元素可使用符号 var[number]
来初始化。
脚本使用 declare -a var
语句来指定一个数组。
数组访问:通过下标
的方式访问 — ${var[number]}
。数组元素的下标由0开始
,和C语言类似。下标可以是整数
或算术表达式
,其值应大于或等于0
。
在数组中,${#array[*]}
和 ${#array[@]}
表示数组中元素的个数
。
初始化方式
shell中使用括号来表示数组,元素之间则使用 空格符号
分隔。
# 等号两边不能空格
array_name=(element_1 element_2 ... element_N)
# 声明偶数
arr_odd=(1 3 5 7 9)
获取数组中的元素
# 数组名[索引] 方式
$(array_name[index])
# 示例
echo ${arr_odd[2]}
打印数组中所有元素
${arr_odd[*]} # 建议使用该方式
${arr_odd[@]} # 该方式在shellcheck中会无法认可,对
在数组声明时添加一个额外的 declare -a语句
,可加速后续的数组操作速度。
declare -a arr_name=(...)
删除数组元素
在shell中,使用unset命令来删除数组元素。语法格式:
# 删除特定的元素
unset array_name[index]
# 删除整个数组
unset array_name # 使用数组名,不写下标
二维数组
二维数组
本质也是一维数组
。通过 行
和 列
的寻址方式来对数组进行引用和操作。
在一维数组
中由单行
组成,而二维数组
由连续的多行
组成。
分支与循环控制
- 双中括号
[[ ... ]]
结构
在bash中,引入[[ ... ]]
扩展测试命令。这种方式一般直接使用数学符号判断时使用。例如
if [[ “$1” > “$2” ]];then - 双圆括号
((...))
结构
允许进行算术扩展和赋值。例如:a=$(( 5 + 3 ))
。该风格类似于C语言风格中的变量操作处理方式。
if和if嵌套
if/then结构
用来判断命令列表的退出状态码
是否为0
。
- if单分支
语法格式:
if [ condition ];then
command1
command2
...
fi # 注意不能少了fi结尾
#例如
if [ "$1" -gt 18 ];then
echo "you are an adult"
fi
- if多分支
语法格式:
if [ condition ];then
command1
command2
...
else
command3
fi
#例如
if [ "$1" -gt 18 ];then
echo "you are an adult"
else
echo "You are a minor and you should study hard"
fi
- if嵌套
语法格式:
if [ condition1 ];then
if [ condition2 ];then
command1
...
fi
fi
for循环
语法格式:
# [list] 是一个列表,类似list1 list2 list3 ... listN
for arg in [list];do #如果do和for在同一行,则注意中间加个分号
command1
command2
...
done
具体实例:
# 方式 1
for i in {1..4};do # 类似python中使用in的方式判断
echo "This is No $i"
done
# 方式 2
for((i=1;i<=5;i++));do # 类似C语言风格来实现
echo "This is No $i"
done
while循环语句
在循环的开头判断条件是否满足,如果条件为True
,则一直循环。
while适合循环次数未知的情况。
语法格式:
while [ condition ];do
command1
command2
...
done
具体实例:计算两个数字之间的和(程序很简单,是本人Test所以加了一些说明)
echo "-------This program calculates the sum of all the numbers between two numbers-------"
echo "please inpput first number (need Must be less than the second number): "
read a
echo "Please input second number (Must be greater than the first number): "
read b
sum=0
while ((a <= b));do
((sum+=a))
((a++))
done
echo "the plus is : $sum"
until循环语句
在循环的顶部判断条件,如果condition为False
,就进入循环,和while语句相反。
语法格式:
until condition;do # 如果condition为True,直接结束循环
command1
command2
...
done
实例:计算1~50的和
#程序使用C语言风格,如果使用shellcheck是会直接报错
set i=1
sum=0
until ((i>50));do
((sum+=i))
((i++))
done
echo "The puls is : $sum"
break continue
直接影响循环行为的命令:break
和 continue
。
和C语言的方式一致,不做过多说明。
- break 直接跳出循环
- continue 只跳过本次循环,忽略本次循环剩余代码,直接进入下一次循环。
case 类型
case结构语句类似C语言中的switch语句。个人使用场景:写多个dockerfile(如ubuntu16.04、ubuntu18.04、centos7.2等)则使用一个变量控制,保证会执行的命令。
语法格式:
case arg/expression in
condition_1)
command_1
;;
condition_2)
command_2
;;
......
condition_N)
command_N
;;
*)
command
esac
⚠️注意:
- 每句测试行,都以
右小括号)
结尾. - 每个判断语句块都以
一对分号;;
结尾。 - case块以
esac(case的反向拼写)
结尾。
具体实例:打印成绩评级
#已进行shellcheck检查
echo "Please input your Score : "
read -r score
case $score in #固定格式,判断数字,然后直接类似C语言中的goto语句
[9][0-9]|100) # 十位 和个位的组合
echo "The Level is A"
;; # 固定格式
[8][0-9]|90)
echo "The Level is B"
;;
[67][0-9]|80)
echo "The Level is C"
;;
[0-5][0-9]|[0-9])
echo "The Level is D, please pay attention it"
;;
*) #固定格式
echo "The input is False"
esac # 注意结尾不能少
select结构语句
select结构语句
和case结构语句
类似,是建立menu的一种工具。
select是从ksh中引入。
语法格式:
select arg in [list];do
command_1
command_2
......
break # 一定要使用break,否则会直接一直提示你选择内容,无法退出(只能通过ctrl+c方式进行)
done
提示用户输入选择的内容
(比如放在变量列表中). 注意: select命令使用PS3提示符
, 默认为 (#?
), 可修改。
具体实例:
#已进行shellcheck检查
PS3="Please choose the OS you are using : " #直接将提示字符串赋值给PS3变量,即可替代符号 #?
select os_type in "ubuntu1604" "Ubuntu1804" "Centos8" "OpenEuler";do
echo "The OS you are using : $os_type"
break
done
exit 0
函数
函数:实现一系列操作的代码块(完成特定task)
。一个函数就是一个子程序。
目的:提高代码的重用性。
自定义函数
语法格式:
# 方式 1
function func_name(){ # function在shell中专门定义函数
command1
command2
...
[return value]
}
# 方式 2 : 简化写法
function_name(){
command1
command2
...
[return value]
}
⚠️注意:
- 关键字function可有可无。
- 函数定义必须在第一次调用函数之前完成。
- 一个函数可以嵌套另一个函数。
- 不用在函数中指明参数,只需在调用时传递参数即可。
函数的调用
在shell中,调用函数时可直接使用名字即可。如果有参数,设置即可。
func_name [param_1] [param_2] ... [param_N]
具体实例:
# 最简单的例子
function print_infor(){
echo "My Name is : $1"
echo "My Age is : $2"
}
print_infor solerho 26
字符串的显示颜色
ANSI定义了屏幕属性相关颜色输出的转义码来表示。
一般会看到打印信息中显示特殊的颜色。通过echo带颜色属性,以及参数 -e
。语法格式如下:
# 方式 1 ---- 容易出现数字混乱
echo -e "\033[字背景颜色;文字颜色m 字符串\033[0m"
# 方式 2 ---- 看起来简洁
echo -e "\e[字背景颜色;文字颜色m 字符串\e[0m"
说明:echo中 -e
是启用转义序列
。其中字体或者背景等编号都会以 m 结尾
。
颜色 | 字体颜色 | 背景颜色 | 显示控制说明 |
---|---|---|---|
黑 | 30m | 40m | 0m ---- 关闭所有属性 |
红 | 31m | 41m | 1m ---- 设置字体高亮(也就是粗体字) |
绿 | 32m | 42m | 2m ---- 设置字体变暗(也就是灰字) |
黄 | 33m | 43m | 3m ---- 设置斜体 |
蓝 | 34m | 44m | 4m ---- 设置字体下划线 |
紫 | 35m | 45m | 5m ---- 设置字体闪烁 |
青 | 36m | 46m | 7m ---- 设置颜色反转 |
白 | 37m | 47m | 8m ---- 设置隐藏(如Linux中输入密码) |
具体实例:
# 已进行shellcheck检查
echo -e "\033[30m This is Black Font \033[1m"
echo -e "\033[31m This is Red Font \033[1m"
echo -e "\033[32m This is green Font \033[1m"
echo -e "\033[33m This is yellow Font \033[1m"
echo -e "\033[34m This is Blue Font \033[1m"
echo -e "\033[35m This is Purple Font \033[1m"
echo -e "\033[36m This is Cyan Font \033[1m"
echo -e "\033[37m This is White Font \033[1m"
echo -e "\033[40m This is Black background \033[1m"
echo -e "\033[41m This is Red background \033[1m"
echo -e "\033[42m This is green background \033[1m"
echo -e "\033[43m This is yellow background \033[1m"
echo -e "\033[44m This is Blue background \033[1m"
echo -e "\033[45m This is Purple background \033[1m"
echo -e "\033[46m This is Cyan background \033[1m"
echo -e "\033[47m This is White background \033[1m"
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5hhyTZEF-1658150017453)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20220529220739489.png)]
IO重定向
该部分不谈基本原理和具体实现,具体可查看 csapp 和 Linux内核中fd内容分析
shell脚本(Linux中保存log等操作也是如此)中,常用的I/O重定向相关的文件描述符(file description,简写fd)
有3个:
- stdin ----- 标准输入 ----- 0 ----- 键盘
- stdout ----- 标准输出 ----- 1 ----- 屏幕
- stderr ----- 标准错误 ----- 2 ----- 错误消息输出到屏幕上
重定向符号及功能说明
符号 | 描述 | 注意点 | 用法例子 |
---|---|---|---|
:> filename 或 > filename | 如果文件存在,则创建一个0长度的文件(与touch类似) | : 是一个占位符,不产生任何输出 | |
1>filename | 重定向stdout 到文件 filename中 | ||
1>>filename | 如果文件存在,则直接重定向追加到文件filename后面,如果不存在,则创建。 | ||
2>>filename | 重定向并追加stderr到文件filename | ||
&>filename | 将stdout 和 stderr 都重定向到文件filename | ||
2>&1 | 重定向stderr到stdout,将错误消息的输出,发送到与标准输出所指向的地方 | ||
i>&j | 重定向文件描述符i到j,指向i文件的所有输出都发送到j | ||
>&j | 默认的,重定向fd 1(stdout)到j,所有传递到stdout的输出都送到j中去 | ||
0<filename 或 < filename | 从文件中接受输入 | grep search_word < filename | |
[j] <> filename | 将filename打开,然后将fd j分配给他,如果filename不存在,则创建。 | 如果fd未指定,则默认fd是0。 |
关闭文件描述符
该使用场景本人暂未遇到,但是看到一些code在使用。
符号 | 说明 |
---|---|
n<&- | 关闭输入文件描述符n |
0<&-,<&- | 关闭stdin |
n>&- | 关闭输出文件描述符n |
1>&-,>&- | 关闭stdout |
代码块重定向
代码块:就是 {}
括起来的命令。例如:for循环、while循环、until循环、case语句等。
具体用法:将重定向命令符号写在代码块的结尾。具体实例:
echo "This is Code block redirect Example"
echo
{
echo "SolerHO";
echo "shell";
echo "55"
} > infor.log # 将代码块重定向输出到infor.log 文件中
{
read -r name;
read -r dev_lang;
read -r age
} < infor.log # 将infor.log重定向输入到代码块
echo "My Name is $name, The programming language being used is $dev_lang, age is $age"
正则表达式
正则表达式(Regular Expression,简称regex或RE):由一系列的特殊字符
组成的字符串
,每个特殊字符
都称为 元字符
(一般解释为特定的含义)。
主要目的:用于搜索文本和字符串的操作。
一般情况下,可以通过 https://tool.oschina.net/regex/ 来验证自己写的是否可以匹配预期想要的结果。
13.1 正则表达式组成
正则表达式由普通字符
和元字符(也称为通配符)
组成的集合
,用来查找匹配特定规则的字符文本。
一个正则表达式中,会包含以下一种或者三种:
-
一个字符集:只包含表示
字面意义的普通字符
。 -
锚:指定所要匹配的文本在文件中所处的位置。如
^
和$
。 -
修饰符:扩大或缩小匹配范围
-
- 常见的修饰符:
星号(*)
、括号
和反斜杠(\)
。
- 常见的修饰符:
13.2 POSIX字符类 [:class:]
字符 | 描述 | ⚠️注意点 |
---|---|---|
[:alnum:] | 匹配字母和数字,等价于A-Za-z0-9 | |
[:alpha] | 匹配字母,等价于 A-Za-z | |
[:blank:] | 匹配一个空格或一个制表符(tab) | |
[:cntrl:] | 匹配控制字符 | |
[:digit:] | 匹配十进制数字,等价于0-9 | |
[:graph:] | 打印任何可视的字符。ASCII码范围:33 ~ 126 之间的字符 | 不包括空格字符(空格字符的ASCII码是32) |
[:print:] | 打印任何可视的字符。ASCII码范围:33 ~ 126 之间的字符 | 包含空格 |
[:lower:] | 匹配小写字母,等价于 a-z | |
[:upper:] | 匹配大写字母,等价于A-Z | |
[:space:] | 匹配空白字符(空格和水平制表符) | |
[:xdigit:] | 匹配16进制数字,等价于 0-9A-Fa-f |
POSIX字符类
通常都要用引号
或双中括号
([[ ]]
)引起来。
13.2 扩展RE字符
字符 | 描述 | ⚠️注意点 |
---|---|---|
星号 — * | 匹配它前面字符的任意多次,包括0次 | |
点 — . | 匹配任意一个字符,除了换行符 | ⚠️注意:不包含换行符 |
脱字符号 — ^ | 匹配行首 | 有时候也表示字符集取反 |
美元符 — $ | 在RE中匹配行尾 | 放在字符的后面,例如 HO$ — 表示以 HO结尾的字符 |
中括号 — […] | 在RE中,匹配中括号内字符集中的某一个字符 | 匹配其中之一 |
反斜杠 — \ | 转义某个特殊含义的字符 | 如 $ 符号,使用反斜杠后,则表示普通字符 |
问号 — ? | 匹配它前面字符 | 只能匹配1次或0次,一般用来匹配单个字符 |
加号 — + | 匹配它前面字符,一次或者多次 | 不能匹配0次的情况 |
竖线 — | | 或操作符 | 匹配其中之一即可 |
转义的尖括号 — <…> | 匹配单词边界 | 括号需使用转义符,否则就是普通的字符 |
转义的大括号 — {…} | 括号中使用数字,则表示数字前面的RE匹配的次数 | 括号需使用转义符,否则就是普通的字符 |
13.1 应用场景
- Linux文本处理:sed、grep、awk、cat、tail、head、tee、uniq、sort
- Linux工具:vim
- 其他的编程语言