Shell 字符串操作与运算符
文章目录
- Shell 字符串操作与运算符:核心语法与实战指南
- 一、字符串操作:从定义到高级用法
- 1. 字符串定义:单引号 vs 双引号(核心区别)
- 2. 计算字符串长度:`${#字符串}`
- 实战示例
- 3. 提取子字符串:`${字符串:索引:长度}`
- 实战示例(以 `str="this is zjl"` 为例,索引分布如下)
- 4. 查找字符位置:`expr index "字符串" "子字符串"`
- 实战示例
- 二、Shell 运算符:算术、逻辑与条件判断
- 1. 算术运算符:处理数值计算
- 两种常用计算方式
- 实战示例
- 2. 逻辑运算符:判断条件是否成立
- 核心逻辑与语法
- 实战示例(结合 `if` 条件判断)
- 三、常见避坑点总结
Shell 字符串操作与运算符:核心语法与实战指南
在 Shell 脚本中,字符串处理和运算符是实现数据处理、逻辑判断的基础能力。无论是拼接字符串、计算数值,还是判断条件是否成立,都离不开这两类语法。本文基于你整理的核心要点,结合实战案例,系统讲解字符串操作和运算符的用法,帮你快速上手并避坑。
一、字符串操作:从定义到高级用法
字符串是 Shell 中最常用的数据类型,涉及“定义、长度计算、子串提取、字符查找”等核心操作,不同场景下需灵活选择引号和语法。
1. 字符串定义:单引号 vs 双引号(核心区别)
字符串的定义必须通过引号(或无引号,有限制),单引号和双引号的核心差异在于“是否识别变量”,这是日常使用中最容易混淆的点。
引号类型 | 核心特性 | 适用场景 | 示例 |
---|---|---|---|
单引号 ' | 不识别变量、不解析特殊字符(如 $ 、\ ),输入什么就输出什么 | 字符串为“纯固定文本”,不含变量或特殊符号 | str='Hello $name' echo $str → 输出 Hello $name ($name 未解析) |
双引号 " | 识别变量(替换为变量值)、解析部分特殊字符(如 \n 、\t ),保留空格 | 字符串含变量、空格或需要换行/制表符 | name="Linux" str="Hello $name" echo $str → 输出 Hello Linux ($name 被解析) |
补充:无引号的限制
若字符串不含空格和特殊字符,可省略引号(如str=test
);但含空格或变量时必须用双引号(如str="test $name"
),否则 Shell 会把空格后的内容当作命令参数,导致语法错误。
2. 计算字符串长度:${#字符串}
语法 ${#变量名}
可直接获取字符串的长度(包含空格和特殊字符),无需额外工具,效率高。
实战示例
# 1. 普通字符串(无空格)
str1="Shell"
echo "str1 长度:${#str1}" # 输出:5(S h e l l 共5个字符)# 2. 含空格的字符串
str2="this is zjl"
echo "str2 长度:${#str2}" # 输出:11(含2个空格:t h i s 空格 i s 空格 z j l)# 3. 含变量的字符串(先解析变量,再算长度)
name="zjl"
str3="hello $name"
echo "str3 长度:${#str3}" # 输出:9(hello 空格 z j l → 5+1+3=9?注意:hello是5个字符,空格1个,zjl3个,共9,需实际计算)
3. 提取子字符串:${字符串:索引:长度}
从字符串中截取部分内容,语法规则:
- 索引:从 0 开始(字符串第一个字符的索引为 0);
- 长度(可选):不写则默认提取到字符串末尾。
实战示例(以 str="this is zjl"
为例,索引分布如下)
字符 | t | h | i | s | (空格) | i | s | (空格) | z | j | l |
---|---|---|---|---|---|---|---|---|---|---|---|
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
str="this is zjl"# 1. 只写索引:从索引5开始,提取到末尾
echo "${str:5}" # 输出:is zjl(索引5是i,后续字符为 is 空格 zjl)# 2. 索引+长度:从索引4开始,提取3个字符
echo "${str:4:3}" # 输出: is(索引4是空格,后续3个字符:空格 i s)# 3. 索引为负:从字符串末尾开始(Bash 4.2+支持,需注意环境)
echo "${str: -3}" # 输出:zjl(末尾3个字符,注意索引前有空格)
4. 查找字符位置:expr index "字符串" "子字符串"
通过 expr index
查找“子字符串中任意单个字符”在“原字符串”中首次出现的位置,注意两点:
- 查找单位是“单个字符”,而非“完整子字符串”;
- 位置从 1 开始(区别于提取子串的 0 开始索引)。
实战示例
str="this is zjl"# 1. 查找单个字符:找 "i" 首次出现的位置
echo `expr index "$str" "i"` # 输出:3(原字符串索引2是i,对应位置3)# 2. 查找多个字符:找 "s" 或 "z" 首次出现的位置
echo `expr index "$str" "sz"` # 输出:4("s" 在原字符串索引3,对应位置4,比"z"的位置8早)# 3. 注意:不识别完整子字符串,只认单个字符
echo `expr index "$str" "is"` # 输出:3(找 "i" 或 "s","i" 首次出现位置3,而非 "is" 整体的位置5)
二、Shell 运算符:算术、逻辑与条件判断
Shell 本身不支持直接运算,需通过 expr
、$((...))
等工具实现,运算符分为“算术运算符”和“逻辑运算符”,分别用于数值计算和条件判断。
1. 算术运算符:处理数值计算
常用算术运算符包括加(+)、减(-)、乘(*)、除(/)、取余(%),需注意 *
需转义(因为 *
在 Shell 中是通配符,代表所有文件)。
两种常用计算方式
计算方式 | 语法 | 特点 | 示例 |
---|---|---|---|
expr 命令 | expr 数值1 运算符 数值2 | 需空格分隔,* 需转义,不支持复杂计算 | expr 23 \* 24 → 输出 552(* 转义为普通乘法符号) |
$((...)) 扩展 | $((数值1 运算符 数值2)) | 无需空格和转义,支持嵌套计算,效率高 | $((23 * 24)) → 输出 552(* 直接用,无需转义) |
实战示例
# 1. 基础计算(加、减、乘、除、取余)
echo "23 + 24 = $(expr 23 + 24)" # 输出:23 + 24 = 47
echo "23 - 24 = $((23 - 24))" # 输出:23 - 24 = -1(支持负数)
echo "23 * 24 = $(expr 23 \* 24)" # 输出:23 * 24 = 552(expr需转义*)
echo "24 / 23 = $((24 / 23))" # 输出:24 / 23 = 1(整数除法,舍去小数)
echo "24 % 23 = $((24 % 23))" # 输出:24 % 23 = 1(取余,24除以23余1)# 2. 嵌套计算(仅 $((...)) 支持)
echo "(23 + 24)* 2 = $(((23 + 24) * 2))" # 输出:(23 + 24)* 2 = 94
2. 逻辑运算符:判断条件是否成立
逻辑运算符用于组合多个条件,判断结果是否成立(Shell 中用 0 表示成立,非 0 表示不成立),常用的有“与(&&)”“或(||)”“非(!)”。
核心逻辑与语法
逻辑运算符 | 含义 | 等价写法(test /[ ] 中) | 规则 | 示例(判断 23>5 且 8<10) |
---|---|---|---|---|
&& | 逻辑与 | -a | 前后条件都成立,整体才成立 | [ 23 -gt 5 ] && [ 8 -lt 10 ] → 成立(返回 0) |
` | ` | 逻辑或 | -o | |
! | 逻辑非 | ! | 条件不成立时,整体才成立 | ! [ 23 -lt 5 ] → 成立(23<5 不成立,非运算后成立) |
实战示例(结合 if
条件判断)
# 1. 逻辑与(&&):两个条件都成立才执行
age=25
score=85
if [ $age -ge 18 ] && [ $score -ge 80 ]; thenecho "成年且成绩优秀" # 输出:成年且成绩优秀(两个条件都成立)
fi# 2. 逻辑或(||):一个条件成立就执行
if [ $age -lt 18 ] || [ $score -lt 60 ]; thenecho "未成年或成绩不及格" # 不输出(两个条件都不成立)
fi# 3. 逻辑非(!):条件不成立才执行
if ! [ $score -lt 60 ]; thenecho "成绩及格" # 输出:成绩及格(score<60 不成立,非运算后成立)
fi
三、常见避坑点总结
*
转义问题:用expr
计算乘法时,*
必须转义(\*
),而$((...))
中无需转义;- 字符串索引与位置差异:提取子串用 0 开始索引,
expr index
用 1 开始位置,不要混淆; expr index
单字符查找:它只查找“单个字符”,不能查找完整子字符串(如找“is”需用其他方法,如grep -bo
);- 逻辑运算符的适用场景:
&&
/||
可直接在命令行用,-a
/-o
仅在[ ]
/test
中用,不要混用(如[ 1 -eq 1 -a 2 -eq 2 ]
正确,[ 1 -eq 1 && 2 -eq 2 ]
错误)。
通过掌握字符串操作和运算符,你可以实现脚本中的数据处理(如截取日志关键词、计算统计数据)和逻辑判断(如多条件验证用户输入),为编写复杂脚本打下基础。