Zsh的变量、语句与字符串

用户与硬件的关系

stateDiagram User --> API API --> User API --> Kernel Kernel --> API Kernel --> Hardware Hardware --> Kernel

Shell的变量功能

变量定义

  1. 等号两端不能有空格

  2. 如有空格 等特殊字符需要加引号" "

  • 双引号、单引号都可以
  • 双引号里可以加变量,单引号不行
  1. 字符串里可以使用转义字符
1
str1="abc\tdef\n"
  1. 数值计算需要双圆括号
1
2
3
num3=$(($num1 + $num2))
# 也省略括号中的取值符号
num3=$((num1 + num2))
  1. 简单的字符操作
1
2
3
str2=abcdef
echo $str2[2,4] # 角标与元素位置相同
echo $str2[1,-1] # -1代表最后一个字符

2.2 变量比较

  1. 使用双圆括号比较数值
1
2
num=123
((num == 123)) && echo good
  • 可以使用&& || !等逻辑操作符
  1. 使用双方括号比较字符串
1
2
3
str=abc
# 注意,两边的变量必须与[]之间留有一个空格!!!
[[ $str == abc ]] && echo good

2.3 变量进阶

2.3.1 typeset

1
2
typeset -A 
暂定

2.3.2 local

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 强制大小写

# l代表lower u代表upper
local -l(u) str

# 设置环境变量

local -x str
export str

# 设置只读变量 

local -r str

# 设置数组不包含重复元素

local -U array

# 设置整数位数

local -Z n num # 设置num的数位为n位。不足补0,超过截断高位

# 设置进制

local -i n num # 设置num为n进制数
[#n] num # 可以显示十进制数为n进制

# 同时对多个变量赋相同而的值

local {a,b,c}=123

# 绑定字符串和数组

local -T(tie) DIR dir
dir=(.. .. ..) # 删除DIR也会删除dir,反之亦然

# 显示变量的定义方式

local -p(print) str

三、语句

3.1 条件语句

3.1.1 格式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# [[ ]] 用于比较字符串和文件

if [[ ]] {
} elif {
} else {
}

# (())用于比较数值

if (()) {
}

# () 用于在子shell运行命令并判断结果
if () {
}
  • 以上三种可以混合使用

3.1.2 示例

1
2
3
4
5
# 此处不需要$
if (( num > 3 && num + 3 <= 10))
{
	echo $num
}

3.2 循环语句

3.2.1 while与until

1
2
3
4
5
6
7
8
9
while [[ ]](( ))( ) # 此处同if
{
	break/continue
}

until [[ ]](( ))( ) # 此处同if
{
	break/continue
}

3.2.2 for

  1. 用于枚举
1
2
3
4
5
# 枚举括号中的内容
for i ( ) 
{

}
  1. C风格的for循环
1
2
3
4
for (( i=0; i< 10; i++ ))
{
	echo $i
}
  1. 生成数组
1
2
3
4
for ({1..10}) 
{
	echo $i
}

3.2.3 repeat

  • 用于循环固定次数
1
2
3
4
5
# 将代码块中的内容循环n次
repeat n
{
...
}

3.3 分支语句

3.3.1 case

1
2
3
4
5
6
case $i
{
(a)
echo 1

}

3.3.2 select

  • 循环,并让用户选择
1
2
3
4
select $i (...)
{

}

3.4 异常处理语句

  • 如果Code 1出错,就执行Code 2
1
2
3
4
5
6
{
	Code 1
} always
{
	Code 2
}

四、字符串处理

4.1 字符串长度1

1
2
3
4
5
6
7
#显示字符串长度

echo $#str 

# 读取函数或脚本的第一个参数的长度 

echo $#1

4.2 字符串拼接

1
2
3
4
5
6
str1=abc
str2=def
# 第一种拼接方式
str2+=$str1
# 第二种拼接方式
str3=$str1$str2

4.3 字符串截断

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
str=abcdeabcde

# 删除左端匹配内容,最小匹配
echo ${str#*b}
# 结果
cdeabcde

# 删除右端匹配内容,最大匹配 
echo ${str%*d}
# 结果
abcdeabc

# 删除左端匹配内容,最大匹配
echo ${str##*b}
# 结果
cde

# 删除右端匹配到的内容
echo ${str%%d*},最大匹配
# 结果
abc

4.4 字符串查找

  1. 子字符串定位
1
2
3
4
5
6
7
str=abcdef

# I 表示从右往左找,i表示从左往右找

echo $str[(I)cd] # $后不能有空格

# 找不到就返回(数组大小+1)

4.5 字符串替换

  1. 只替换找到的第一个
1
2
str=abcabc
echo ${str/bc/ef}
  1. 删除匹配到的第一个
1
echo ${str/bc}
  1. 替换所有找到的
1
echo ${str//bc/ef} # 多加一个/
  1. 删除所有匹配的
1
echo ${str//bc}
  1. 匹配成功就输出空字符串
1
echo ${str:#ab*}
  1. 匹配失败就输出原字符串
1
echo ${str:#ab}
  1. M后效果反转
1
echo ${(M)str:#ab}
  1. 按位置删除(替换)字符串
1
2
str[1,4]=  # 空值即位删除,否则就是替换
echo $str

4.6 判断字符串变量是否存在

1
2
3
(($+var)) && echo good

# 存在就返回good
  • 仅仅用[["str"==""]]是无法区分其内容为空还是不存在的

4.7 字符串匹配判断

  1. 判断是否包含字符串
1
2
3
4
str1=abc
str2=bc

[[ $str1 == *$str2* ]] && echo good

4.8 大小写转换

  1. 转成大写
1
2
3
4
5
6
7
str="ABCDE abcde"

echo ${(U)str}

# 等价形式

echo ${str:u}
  1. 转成小写
1
2
3
4
5
echo ${(L)str}

# 等价形式

echo ${str:l}
  1. 转成首字母大写
1
echo ${(C)str}

4.9 文件目录名截取

1
2
3
filepath=/a/b/c.x

echo ${filepath:[hter]}
  • h取目录名
  • t取文件名
  • e取文件扩展名,即文件.后的部分
  • r去掉末尾扩展名的路径

4.10 字符串分隔

  1. 使用空格 作分隔符,多个空格只算一个分隔符
1
2
3
4
5
str='aa bb cc dd'

# 显示第n个token

echo ${str[(w)n]}
  1. 指定分隔符
1
2
3
4
5
str="aa--bb--cc"

# 设定分隔符为--,并显示第n个token

echo ${str[(ws:--:)n]}

4.11 多行字符串

1
2
3
# 以下操作可以用于命令行
str="line1
> line2"

4.12 读取文件内容到字符串

  1. 读取整个文件
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
str=$(<filename)

# 注意引号

echo "$(<filename)"

# 遍历每行

for i (${(f)"$(<filename)"})
{
	echo $i
}
  1. 读取文件指定行
1
2
3
4
5
6
7
8
9
echo ${"$(<text.txt)"[(f)2]}

# 输出包含abc的一行

echo ${"$(<text.txt)"[(fr)*abc*]}

# 从左端输出包含aa的一行,但从左端截去"line" 

echo ${"$(<text.txt)"[(fr)*aa*]#line}

  1. #表示从字符串开头开始匹配,%表示从字符串结尾开始匹配 ↩︎

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy