Linux:expr命令、测试条件表达式、正则表达式入门教程
在Udig.sh文件中,使用了测试条件表达式和正则表达式,还使用了expr
命令。起初,我以为测试条件表达式和正则表达式是一种表达式,但是在学习了解后发现并不是如此。在Shell脚本中,测试条件表达式用于在条件语句(如if
、while
等)中进行条件判断;正则表达式是一种用于匹配和操作文本的强大工具,可用于查找、替换、提取文本中的特定模式;expr 命令主要用于计算表达式的值或进行简单的模式匹配。
3.1 expr
命令
expr
命令是一个在Shell脚本中常用的命令,用于执行各种表达式运算,包括算术运算、字符串操作和模式匹配等。它在早期的Unix系统中非常流行,现代Shell(如Bash)提供了更强大的内置表达式处理功能,但expr
命令仍然在一些脚本中使用。其基本语法是:expr 表达式
。expr
常用功能如下所示:
(1)算数运算
expr
命令可以执行常用的算术运算,包括加、减、乘(\*
)、除(/
)和取模(%
)。例如,先定义变量 a 和 b,再进行他们的除法操作:
a=10
b=3
quot=$(expr $a / $b)
echo "Quotient: $quot"
# 输出:Quotient: 3
(2)字符串操作
expr
命令可以执行常用的的字符串操作,如字符串长度、子字符串提取和字符串比较等。字符串长度:expr length "$string"
;子字符串提取:expr substr "$string" $开始位数 $截取长度
;字符串匹配:expr match "$string" '$匹配的内容'
。下面的代码以常用的Hello, World!
为例:
string="Hello, World!"
# 字符串长度计算
len=$(expr length "$string")
echo "Length: $len" # 输出:Length: 13
# 子字符串提取第1位开始,截取5位
sub=$(expr substr "$string" 1 5)
echo "Substring: $sub" # 输出:Substring: Hello
# 从字符串的开头开始匹配模式 Hello.*。
# .* 表示匹配任意字符(包括空字符)零次或多次,输出匹配到的字符串的长度
match=$(expr match "$string" 'Hello.*')
echo "Match: $match" # 输出:Match: 13;
上述代码匹配时使用了模式匹配返回匹配的字符串长度,如果要返回匹配的部分,可以使用 expr :
结合正则表达式来返回匹配的部分,其中'Hello\(.*\)'
也是一个正则表达式。
match_part=$(expr "$string" : 'Hello\(.*\)')
echo "Match Part: $match_part"
# 输出:Match Part: , World!
3.2 测试条件表达式
在Shell脚本中,测试条件表达式用于在条件语句(如if
、while
等)中进行条件判断。测试条件表达式可以检查文件属性、比较字符串、数值运算等。测试条件表达式通常使用test 表达式
、方括号[]
或双括号[[ ]]
来表示,其中双括号[[ ]]
是Bash的扩展,提供了更多的功能和更严格的语法检查。test
是一个内置的 Linux 命令,用于评估条件表达式,并根据结果返回一个0或1。基本语法:test expression
,例如test -e hello.txt
检查 hello.txt
是否存在。而[ ]
可以说是 test
命令的另一种形式,[ -e file.txt ]
、[[ -e file.txt ]]
与 test -e file.txt
功能相同。当具有多个条件时,可以使用逻辑与&&
、逻辑或||
来将多个条件连接。测试条件表达式常用于字符串测试、文件测试、数字测试,主要参数和功能如下:
(1)文件测试
命令 | 功能 |
---|---|
-f 文件 | 文件是否存在且为普通文件 |
-d 文件 | 文件是否存在且为目录 |
-e 文件 | 文件是否存在 |
-r 文件 | 文件是否存在且可读 |
-w 文件 | 文件是否存在且可写 |
-x 文件 | 文件是否存在且可执行 |
-s 文件 | 文件是否存在且大小大于 0 |
-L 文件 | 文件是否存在且为符号链接 |
(2)字符串测试
命令 | 功能 |
---|---|
-z 字符串 | 字符串是否为空 |
-n 字符串 | 字符串是否非空 |
字符串 1 = 字符串 2 | 字符串 1 是否等于字符串 2 |
字符串 1!= 字符串 2 | 字符串 1 是否不等于字符串 2 |
字符串 1 | 字符串 1 是否非空(等同于 -n 字符串 1) |
(3)数字测试
命令 | 功能 |
---|---|
数值 1 -eq 数值 2 | 数值 1 是否等于数值 2 |
数值 1 -ne 数值 2 | 数值 1 是否不等于数值 2 |
数值 1 -gt 数值 2 | 数值 1 是否大于数值 2 |
数值 1 -lt 数值 2 | 数值 1 是否小于数值 2 |
数值 1 -ge 数值 2 | 数值 1 是否大于或等于数值 2 |
数值 1 -le 数值 2 | 数值 1 是否小于或等于数值 2 |
3.3 正则表达式
正则表达式(Regular Expression)是一种用于匹配和操作文本的强大工具,其通过定义一系列的字符和特殊符号,来描述一个或多个文本模式,可用于搜索、替换、提取文本中的特定信息。正则表达式中的部分命令也可以用在测试条件表达式和expr命令中,并且不同语言都具有正则表达式,但是可能有一定的区别。
Python 中使用 re
模块进行正则表达式操作,JS中使用使用斜杠 /
包围正则表达式模式或者使用RegExp
构造函数。在 Bash 中,正则表达式还可以结合 grep
、sed
、awk
等工具使用,使用 grep
进行模式匹配,使用 sed
进行模式替换。
正则表达式的语法挺多,在bing中直接搜索正则表达式时,可以看到好几个正则表达式大全网页,并且还看到了一个在线练习网站:https://regexlearn.com/zh-cn。基于学多了也记不住、学多了也没用的原则,简单了解一下常用的正则表达式。推荐大家在吃饭或者坐车时,B站随便找个正则表达式的讲解视频看一下,这样就能明白一些常用的指令啦。例如: 30分钟正则表达式教程_哔哩哔哩_bilibili 对指令有一个大概的了解。
(1) 字符
命令 | 功能 | 案例 |
---|---|---|
. | 匹配除换行符以外的任意单个字符 | a.c 可以匹配 "abc" , "a1c" , "a-c" 等 |
\d 或[0-9] | 匹配任意一个数字 | \d\d 可以匹配 "12" , "34" 等 |
\D 或 [^0-9] | 匹配任意一个非数字字符 | |
\w 或 [a-zA-Z0-9_] | 匹配包括下划线的任意一个单词字符 | \w+ 可以匹配 "hello" , "world_123" 等 |
\W 或 [^a-zA-Z0-9_] | 匹配任意一个非单词字符 | |
\s | 匹配任意一个空白字符,包括空格、制表符、换行符等 | a\sb 可以匹配 "a b" |
\S | 匹配任意一个非空白字符 | |
[abc] | 匹配 a , b , 或 c 中的任意一个字符 | [abc]d 可以匹配 "ad" , "bd" , "cd" |
[^abc] | 匹配除 a , b , c 以外的任意一个字符 | [^abc]d 可以匹配 "xd" , "yd" , "zd" 等 |
(2)量词
量词 | 功能 | 案例 |
---|---|---|
* | 匹配前面的元素零次或多次 | a* 可以匹配 "" , "a" , "aa" , "aaa" 等 |
+ | 匹配前面的元素一次或多次 | a+ 可以匹配 "a" , "aa" , "aaa" 等,但不能匹配 "" |
? | 匹配前面的元素零次或一次 | a? 可以匹配 "" 或 "a" |
{n} | 匹配前面的元素恰好 n 次 | a{3} 可以匹配 "aaa" |
{n,} | 匹配前面的元素至少 n 次 | a{3,} 可以匹配 "aaa" , "aaaa" , "aaaaa" 等 |
{n,m} | 匹配前面的元素 n 到 m 次 | a{2,4} 可以匹配 "aa" , "aaa" , "aaaa" |
(3)锚点/边界匹配符
边界匹配符 | 功能 | 案例 |
---|---|---|
^ | 匹配行的开始位置 | ^a 会匹配以 "a" 开头的行 |
$ | 匹配行的结束位置 | a$ 会匹配以 "a" 结尾的行 |
此外,还可以使用()
将多个字符分组,可以用于量词和捕获匹配的部分;也可以使用 |
逻辑或,匹配多个模式中的任意一个。在之前的代码中,使用了 expr "$ls" : '.*-> \(.*\)$'
,这里模式匹配的内容便是正则表达式。这里第一个.\*
来匹配任意字符(除换行符外)零次或多次,用于匹配从字符串开头到->
之前的所有内容;\(
和 \)
用于分组,但使用反斜杠\
进行了转义;第二个.\*
用于匹配->
之后的所有内容,最后的$
是匹配字符串的结束位置。