Shell
第一章 Shell(命令解释器)概念

- 作用: 用户与Linux内核之间的接口/桥梁。
- 核心功能:
- 接收与解释命令: 读取用户输入,理解指令。
- 执行程序: 请求内核运行指定程序。
- 管理I/O: 处理命令的输入输出,支持重定向 (
>,<) 和管道 (|)。 - 脚本编程: 提供编程环境,用于自动化任务 (Shell Scripting)。
- 环境管理: 管理环境变量 (如
PATH)。
环境变量:系统启动时预先定义好的变量,特征:预定义,被广播。
第二章 Shell脚本入门
本章主要介绍Shell脚本的基础知识,包括其标准格式、如何编写您的第一个Shell脚本,以及执行这些脚本的常用方法。
1. 脚本格式
一个规范的Shell脚本通常以 #!/bin/bash 开头。
#!被称为 “shebang”,它告知系统该脚本应由哪个解释器执行。/bin/bash指的是Bash解释器的具体路径。在许多系统中,这可能是/bin/sh或其他Shell的路径,但bash是非常常见的。
2. 第一个Shell脚本:helloworld.sh
创建一个简单的Shell脚本,它会在终端输出 “helloworld”。
步骤:
- 使用文本编辑器(如
vim)创建一个名为helloworld.sh的文件:vim helloworld.sh - 在文件中输入以下内容:
#!/bin/bash 声明脚本解释器 echo "helloworld" - 保存文件并退出编辑器。
3. 脚本的常用执行方式
方式一:使用解释器命令 (bash 或 sh)
直接调用Shell解释器来执行脚本文件。
- 优点: 脚本文件不需要设置可执行权限。
- 语法:
bash 脚本路径或sh 脚本路径(路径可以是相对的或绝对的)。sh ./helloworld.sh bash ./helloworld.sh sh /home/atguigu/helloworld.sh bash /home/atguigu/helloworld.sh - 原理:
bash(或sh) 解析器读取脚本文件内容并逐行执行其中的命令。
方式二:直接执行脚本文件路径
将脚本文件本身作为可执行程序来运行。 前提: 脚本文件 必须 具有可执行权限。
- 首先要赋予helloworld.sh 脚本的+x权限:
chmod +x helloworld.sh
chmod 755 helloworld.sh
-
语法:
./脚本文件名(相对路径) 或/完整路径/脚本文件名(绝对路径)。./helloworld.sh /home/atguigu/helloworld.sh ``` -
原理: 系统通过脚本开头的
#!/bin/bash来确定使用哪个解释器执行脚本内容。
注意:
- 第一种方法是解释器(如
bash)帮助执行脚本,所以脚本本身不需要执行权限。 - 第二种方法是脚本“自己”执行,因此它必须拥有执行权限。
子Shell
子Shell是由一个父Shell启动的独立子进程。它会继承父Shell环境的一个副本(例如,通过 export 导出的变量、当前工作目录),但在子Shell内部所做的环境更改(如定义局部变量、改变当前目录)不会影响到父Shell。这提供了一种环境隔离的机制。
- 环境隔离:执行临时命令或改变设置,而不影响主Shell环境。例如,临时切换目录执行一些操作。
- 命令分组:将一系列命令视为一个单元,常用于统一进行输入/输出重定向或将整个组放到后台执行。
- 并行执行:通过将任务放到后台的子Shell中运行,实现任务的并发处理,提高效率。
- 命令替换:捕获一个或一组命令的输出结果,并将其用作另一个命令的参数或赋值给变量。
第三章 变量
本章介绍Shell脚本中变量的使用,包括系统预定义变量、自定义变量以及特殊变量。
1. 系统预定义变量
Shell环境预先定义了一些变量,方便用户直接使用。
- 常用系统变量:
HOME: 当前用户的家目录。PWD: 当前工作目录。SHELL: 当前使用的Shell解释器。USER: 当前登录的用户名。
- 获取变量值: 使用
$变量名。 - 查看变量值: 使用
echo $变量名。- 示例:
echo $HOME
- 示例:
- 显示所有变量: 使用
set命令。
2. 自定义变量
- 基本语法:
- 定义变量:
变量名=变量值(等号两边不能有空格)。- 示例:
MY_VAR="hello world"(值有空格时用引号)
- 示例:
- 撤销变量:
unset 变量名。 - 声明静态变量 (只读):
readonly 变量名=变量值(不能被unset)。
- 定义变量:
- 变量定义规则:
- 名称可由字母、数字、下划线组成,不能以数字开头,建议环境变量名大写。
- 默认都是字符串类型。
- 值若包含空格,需用单引号或双引号括起来。
- 提升为全局环境变量:
export 变量名,使其可被子Shell程序使用。
3. 特殊变量
Shell提供了一些具有特殊含义的变量。
$n:- 获取脚本的参数。
$0是脚本名,$1是第一个传入参数,$2是第二个参数,以此类推。 - 十以上的参数需用大括号:
${10}。
- 获取脚本的参数。
$#:- 获取传递给脚本或函数的所有输入参数的总个数。
$*:- 将所有输入参数视为一个整体字符串。
- 当被双引号包围时 (
"$*"),所有参数合并为一个字符串,参数间以IFS(默认为空格)的第一个字符分隔。
$@:- 将每个输入参数视为独立的字符串。
- 当被双引号包围时 (
"$@"),每个参数被分别引用为一个独立的字符串。
$?:- 获取上一个命令执行后的退出状态码。
0通常表示成功,非0表示失败。
第四章 运算符
1. 基本语法
在Shell中进行算术运算,主要有两种推荐的格式:
$((运算式))$[运算式]
注意点:
- 运算式中的变量引用可以不加
$符号,例如val而不是$val。 - 运算符和数字/变量之间可以有空格,也可以没有,但建议保持一致性以提高可读性。
- 这两种方式都支持标准的算术运算符,如
+(加),-(减),*(乘),/(除),%(取模)。 - 乘法符号
*在某些上下文中可能需要转义 (如\*) 或用引号包围,但在$((...))和$[...]中通常可以直接使用。
2. 案例实操
计算 (2+3)*4 的值
# 定义变量 S 并计算 (2+3)*4
S=$[(2+3)*4]
# 输出变量 S 的值
echo $S
预期输出:20
使用 $((...))首先,如果之前定义过变量 S,最好先 unset S 来清除它
# unset S
# 定义变量 S 并计算 (2+3)*4
S=$(((2+3)*4))
# 输出变量 S 的值
echo $S
预期输出:20
第五章 条件判断
本章详细介绍Shell脚本中进行条件判断的语法、常用条件以及多条件判断的用法。
1. 基本语法
在Shell中,条件判断主要有两种格式:
test condition[ condition ]
重要注意事项:
- 当使用
[ condition ]格式时,方括号[和]与内部的condition之间 必须有空格。 - 条件表达式如果非空,则通常被认为是
true。例如,[ atguigu ]返回true,而[ ]返回false。 - 命令执行后,可以通过特殊变量
$?来获取其返回状态。如果为0,表示上一个命令正确执行(条件为真);如果为非0,则表示上一个命令执行不正确(条件为假)。
2. 常用判断条件
a. 两个整数之间比较
用于比较两个整数的大小关系。
| 操作符 | 描述 | 英文全称 |
|---|---|---|
-eq | 等于 | equal |
-ne | 不等于 | not equal |
-lt | 小于 | less than |
-le | 小于等于 | less equal |
-gt | 大于 | greater than |
-ge | 大于等于 | greater equal |
案例实操:判断23是否大于等于22
-
使用
test命令:atguigu@ubuntu:~$ test 23 -ge 22 atguigu@ubuntu:~$ echo $? 0 -
使用
[ condition ]格式:atguigu@ubuntu:~$ [ 23 -ge 22 ] atguigu@ubuntu:~$ echo $? 0(输出
0表示条件为真,23大于等于22)
b. 按照文件权限进行判断
用于检查文件是否具有特定的权限。
| 操作符 | 描述 | 英文全称 |
|---|---|---|
-r | 有读的权限 | read |
-w | 有写的权限 | write |
-x | 有执行的权限 | execute |
案例实操:判断 helloworld.sh 是否具有写权限 (假设当前用户对该文件有写权限)
-
使用
test命令:atguigu@ubuntu:~$ test -w helloworld.sh atguigu@ubuntu:~$ echo $? 0 -
使用
[ condition ]格式:atguigu@ubuntu:~$ [ -w helloworld.sh ] atguigu@ubuntu:~$ echo $? 0(输出
0表示条件为真,文件具有写权限)
c. 按照文件类型进行判断
用于检查文件的存在性及其类型。
| 操作符 | 描述 | 英文全称 |
|---|---|---|
-e | 文件存在 | existence |
-f | 文件存在并且是一个常规的文件 | file |
-d | 文件存在并且是一个目录 | directory |
案例实操:判断 /home/atguigu/cls.txt 目录中的文件是否存在 (假设该文件不存在)
-
使用
test命令:atguigu@ubuntu:~$ test -e /home/atguigu/cls.txt atguigu@ubuntu:~$ echo $? 1 -
使用
[ condition ]格式:atguigu@ubuntu:~$ [ -e /home/atguigu/cls.txt ] atguigu@ubuntu:~$ echo $? 1(输出
1表示条件为假,文件不存在)
3. 多条件判断
可以使用逻辑运算符 && (逻辑与) 和 || (逻辑或) 来组合多个条件判断。
command1 && command2:只有当command1成功执行 (返回状态为0) 时,command2才会执行。command1 || command2:只有当command1执行失败 (返回状态非0) 时,command2才会执行。
案例实操:
-
使用
test命令:atguigu@ubuntu:~$ test atguigu && echo OK || echo notOK OK atguigu@ubuntu:~$ test && echo OK || echo notOK notOK -
使用
[ condition ]格式:atguigu@ubuntu:~$ [ atguigu ] && echo OK || echo notOK OK atguigu@ubuntu:~$ [ ] && echo OK || echo notOK notOK在这些例子中:
test atguigu(或[ atguigu ]) 因为atguigu是非空字符串,所以条件为真 (返回0)。因此&&后面的echo OK执行。test(或[ ]) 因为条件为空,所以条件为假 (返回非0)。因此&&后面的echo OK不执行,而||后面的echo notOK执行。
第六章 流程控制
if 判断
if 语句用于根据条件是否成立来执行不同的命令段。
基本语法:
-
单分支:
if [ 条件判断式 ]; then 程序 fi或者,更易读的格式:
if [ 条件判断式 ] then 程序 fi -
多分支:
if [ 条件判断式 ] then 程序 elif [ 条件判断式 ] then 程序 else 程序 fi
注意事项:
[ 条件判断式 ],中括号和条件判断式之间 必须有空格。if关键字后要有空格。
案例实操:
需求:输入一个数字,如果是1,则输出 “banzhang zhen shuai”,如果是2,则输出 “cls zhen mei”,如果是其它,什么也不输出。
脚本 (if_example.sh 内容,根据文档中的 if .sh):
#!/bin/bash
if [ "$1" -eq 1 ]
then
echo "banzhang zhen shuai"
elif [ "$1" -eq 2 ]
then
echo "cls zhen mei"
fi
保存退出。
赋予执行权限:
atguigu@ubuntu:~$ chmod 755 if_example.sh
执行脚本:
atguigu@ubuntu:~$ ./if_example.sh 1
banzhang zhen shuai
```bash
atguigu@ubuntu:~$ ./if_example.sh 2
cls zhen mei
如果输入其他数字(例如 ./if_example.sh 3),则脚本不会有任何输出,因为没有匹配的条件分支,也没有 else 分支来处理其他情况。
case 语句
case 语句用于根据变量的不同取值,执行多个不同的命令分支。它提供了一种比嵌套 if 更简洁的多条件判断方式。
基本语法:
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值2,则执行程序2
;;
# ...省略其他分支...
*) # 匹配其他所有情况
如果变量的值都不是以上的值,则执行此程序
;;
esac
注意事项:
case行尾必须为单词in。- 每一个模式匹配(例如
"值1")必须以右括号)结束。 - 双分号
;;表示一个分支中命令序列的结束,其作用类似于C语言中的break。 - 最后的
*)表示默认模式,如果前面的模式都不匹配,则执行此分支下的程序,相当于C语言中的default。
案例实操:
需求:输入一个数字,如果是1,则输出 “banzhang”,如果是2,则输出 “cls”,如果是其它,输出 “renyao”。
脚本 (case_example.sh 内容,根据文档中的 case .sh):
#!/bin/bash
case $1 in
"1")
echo "banzhang"
;;
"2")
echo "cls"
;;
*)
echo "renyao"
;;
esac
保存退出。
赋予执行权限:
atguigu@ubuntu:~$ chmod 777 case_example.sh # 文档中使用 case .sh
执行脚本:
atguigu@ubuntu:~$ ./case_example.sh 1
banzhang
```bash
atguigu@ubuntu:~$ ./case_example.sh 2
cls
```bash
atguigu@ubuntu:~$ ./case_example.sh 3
renyao
第七章 for 循环
for 循环用于重复执行指定的命令列表。Shell 提供了多种 for 循环的格式。
基本语法 1 (C语言风格):
for ((初始值; 循环控制条件; 变量变化))
do
程序
done
- 说明: 类似于C语言的for循环,用于数值迭代。
- 案例: 从1加到100。
#!/bin/bash sum=0 for ((i=1; i<=100; i++)) do sum=$[$sum+$i] # 或 sum=$(($sum + $i)) done echo $sum # 输出 5050
基本语法 2 (遍历列表):
for 变量 in 值1 值2 值3…
do
程序
done
- 说明: 遍历一个由空格分隔的值列表,或者遍历命令的输出结果,或者脚本参数。
- 案例: 打印列表中的几个名字。
#!/bin/bash for i in cls mly wls do echo "ban zhang love $i" done # 输出: # ban zhang love cls # ban zhang love mly # ban zhang love wls
比较 $* 和 $@ 在 for 循环中的区别(重点):
-
不带双引号时:
$*和$@都以 $1$2 …$n的形式输出所有参数。 -
带双引号时:
"$*":将所有参数视为一个单一的字符串。for i in "$*"循环只会执行一次,变量i的值是所有参数组成的字符串。"$@":将每个参数视为独立的字符串。for i in "$@"会正确地遍历每个参数,即使参数包含空格。这是处理脚本参数的推荐方式。
while循环
while 循环在给定条件为真 (true) 的情况下,重复执行指定的命令列表。
基本语法:
while [ 条件判断式 ]
do
程序
done
注意事项:
[ 条件判断式 ],中括号和条件判断式之间 必须有空格。- 条件判断式通常使用与
if语句中相同的测试条件(例如,整数比较、文件检查等)。 - 循环体会一直执行,直到条件判断式的结果为假 (false,即命令返回非零退出状态码)。
- 必须确保循环内部有改变条件判断式最终结果的逻辑(例如,修改循环变量的值),否则可能导致无限循环。
案例实操:
需求:使用 while 循环计算从1加到100的和。
脚本 (while_example.sh 内容,根据文档中的 while .sh):
#!/bin/bash
sum=0
i=1 # 初始化循环变量
# 当 i 小于或等于 100 时,循环继续
while [ $i -le 100 ]
do
sum=$[$sum+$i] # 累加当前 i 的值到 sum (或者使用 sum=$(($sum + $i)))
i=$[$i+1] # i 自增1 (或者使用 i=$(($i + 1)))
done
# 循环结束后,打印总和
echo $sum
保存退出。
赋予执行权限:
atguigu@ubuntu:~$ chmod 777 while_example.sh # 文档中使用 while .sh
执行脚本:
atguigu@ubuntu:~$ ./while_example.sh
5050
用途:
while 循环非常适用于需要根据某个条件持续执行一段代码块的场景,特别是当循环次数不确定,而是取决于某个动态变化的条件时。
read读取控制台输入
read 命令用于从标准输入(通常是键盘)读取用户的输入,并将其赋值给一个或多个变量。
基本语法:
read (选项) (参数)
选项:
-p:指定读取值时的提示符。- 例如:
read -p "请输入您的名字: " name
- 例如:
-t:指定读取值时等待的时间(秒)。- 如果用户在指定时间内没有输入,
read命令会超时并返回。 - 如果
-t选项后面不加具体的秒数(或者指定为0),则表示一直等待。 - 如果超时,
read命令的退出状态码通常是非零值。
- 如果用户在指定时间内没有输入,
参数:
变量:指定一个或多个变量名,用于存储读取到的值。- 如果只提供一个变量名,所有输入都将赋给该变量。
- 如果提供多个变量名,输入会根据
IFS(内部字段分隔符,默认为空格、制表符、换行符)被分割,并依次赋给这些变量。最后一个变量会接收剩余的所有输入。
案例实操:
需求:提示用户在7秒内输入名称,并读取到变量中,然后打印该变量。
脚本 (read_example.sh 内容):
#!/bin/bash
# -t 7: 等待7秒
# -p "Enter your name in 7 seconds : ": 指定提示信息
# NN: 用于存储输入的变量名
read -t 7 -p "Enter your name in 7 seconds : " NN
# 打印读取到的变量 NN 的值
echo $NN
保存退出。
赋予执行权限:
atguigu@ubuntu:~$ chmod 777 read_example.sh
执行脚本:
-
在7秒内输入:
atguigu@ubuntu:~$ ./read_example.sh Enter your name in 7 seconds : atguigu # 用户输入 "atguigu" 并按回车 atguigu # 脚本输出读取到的值 -
超过7秒未输入(或输入后未及时按回车):
atguigu@ubuntu:~$ ./read_example.sh Enter your name in 7 seconds : # 7秒后,read命令超时 # (NN变量可能为空或者包含超时前输入的部分内容,具体行为可能因shell版本而异) # 脚本会打印 NN 的值,如果超时前无有效输入,则打印空行
用途:
read 命令是Shell脚本中实现用户交互的关键工具,允许脚本动态地从用户那里获取信息。
第八章 函数
系统提供的函数和用户自定义的函数。
1. 系统函数
Shell提供了一些内置的命令或工具,可以视为系统函数,用于处理常见的任务,如路径和文件名操作。
1.1 basename
basename 命令用于从一个路径字符串中提取文件名或目录名,并可以选择性地去除指定的后缀。
基本语法:
basename [string / pathname] [suffix]
- 功能描述:
basename命令会删掉所有的前缀,包括最后一个斜杠 (/) 字符,然后将字符串(通常是文件名)显示出来。可以理解为取路径里的文件名称。 - 选项:
suffix:可选参数。如果指定了suffix,并且它匹配pathname或string的末尾,basename会将这个后缀去掉。
案例实操:
-
截取路径的文件名称:
atguigu@ubuntu:~$ basename /home/atguigu/banzhang.txt banzhang.txt -
截取文件名并去掉指定后缀:
atguigu@ubuntu:~$ basename /home/atguigu/banzhang.txt .txt banzhang
1.2 dirname
dirname 命令用于从一个给定的包含绝对路径的文件名中去除文件名部分(非目录的部分),然后返回剩下的路径(目录的部分)。
基本语法:
dirname 文件绝对路径
- 功能描述: 可以理解为取文件路径的目录部分。
案例实操:
- 获取文件的路径:
atguigu@ubuntu:~$ dirname /home/atguigu/banzhang.txt /home/atguigu
2. 自定义函数
用户可以在Shell脚本中定义自己的函数,以封装可重用的代码块。
基本语法:
[ function ] funname[()]
{
Action; # 函数体,包含一系列命令
[ return int; ] # 可选的返回语句
}
function关键字是可选的。funname是函数的名称。()括号是可选的(但在调用时通常不带括号,除非传递参数)。- 花括号
{}包围函数体。 Action是函数执行的命令。return int用于指定函数的退出状态码(一个0-255之间的整数)。如果省略return语句,函数的退出状态码是函数体中最后一条命令的退出状态码。
经验技巧(注意事项):
- 声明与调用顺序: 必须在调用函数的地方之前先声明函数。Shell脚本是逐行运行的,不会像其他一些编程语言那样先编译整个文件。
- 返回值获取:
- 函数的返回值(退出状态码)只能通过特殊变量
$?来获得。 - 可以使用
return n显式指定返回值n(0-255)。 - 如果不使用
return,则函数的返回值是其内部最后一条命令的执行结果(退出状态码)。
- 函数的返回值(退出状态码)只能通过特殊变量
案例实操:
需求:计算两个输入参数的和。
脚本 (fun_example.sh 内容,根据文档中的 fun .sh):
#!/bin/bash
# 定义一个名为 sum 的函数
function sum() { # 或者直接写 sum() {
s=0
# $1 和 $2 是传递给函数的参数
s=$[$1+$2] # 或者 s=$(($1 + $2))
echo "$s" # 将结果输出到标准输出
}
# 从控制台读取两个数字
read -p "Please input the number1: " n1
read -p "Please input the number2: " n2
# 调用 sum 函数,并将 n1 和 n2 作为参数传递给它
# 函数的输出 (echo "$s") 会在这里显示
sum $n1 $n2
# 如果想获取函数的 return 值 (退出状态码),可以这样做:
# result=$(sum $n1 $n2) # 捕获函数的标准输出到变量 result
# status=$? # 获取 sum 函数的退出状态码
# echo "The sum is: $result"
# echo "Function exit status: $status"
# 注意:如果函数内部有 echo,那么 $() 会捕获 echo 的内容,而不是 return 的数值。
# return 的值主要用于判断函数执行是否成功,通过 $? 获取。
保存退出。
赋予执行权限:
atguigu@ubuntu:~$ chmod 777 fun_example.sh
执行脚本:
atguigu@ubuntu:~$ ./fun_example.sh
Please input the number1: 2
Please input the number2: 5
7
在这个例子中,sum 函数通过 echo "$s" 将计算结果输出到标准输出,调用 sum $n1 $n2 时,这个输出就直接显示在终端了。
第九章 Shell文本处理工具
本章介绍Shell中常用的文本处理工具:cut、awk
1. cut
cut 命令用于按列(字段)、字节或字符剪切文件内容。
基本用法: cut [选项] 文件名
常用选项:
-d "分隔符":指定字段分隔符(默认为制表符)。-f 字段编号:选择要提取的字段(如-f 1,3提取第1和第3字段;-f 2-提取从第2字段到行尾)。-c 字符位置:按字符位置剪切(如-c 1-5提取每行前5个字符)。
示例:
提取 cut.txt 的第一列(以空格分隔):
# 假设 cut.txt 内容:
# dong shen
# guan zhen
cut -d " " -f 1 cut.txt
# 输出:
# dong
# guan
提取 PATH 变量中以冒号分隔的第3个路径之后的所有路径:
echo $PATH | cut -d ":" -f 3-
2. awk
awk 是一个强大的文本分析和处理工具,逐行读取输入,按分隔符(默认为空格)切片并处理。
基本用法: awk [选项] '/模式/{动作}' 文件名
- 模式 (Pattern): 正则表达式或条件,匹配成功则执行对应动作。若省略,则对所有行执行动作。
- 动作 (Action): 一系列命令,通常用
{}包围。若省略,则默认打印匹配的整行 (print $0)。
常用选项:
-F "分隔符":指定输入字段分隔符。-v 变量=值:定义awk内部变量。
核心概念与内置变量:
BEGIN {动作}:在处理任何输入行之前执行。END {动作}:在处理完所有输入行之后执行。$0:当前整行内容。$1, $2, ...:当前行的第1、第2…个字段。NR:当前处理的行号(记录数)。NF:当前行的字段数量。FILENAME:当前输入文件名。
示例:
搜索 passwd 文件中以 root 开头的行,并打印其第7个字段(shell路径),使用冒号作为分隔符:
awk -F ':' '/^root/{print $7}' passwd
# 输出: /bin/bash (示例)
打印 passwd 文件的用户名(第1列)和shell(第7列),并在开头加上标题行:
awk -F ':' 'BEGIN{print "User,Shell"} {print $1","$7}' passwd
第十章 正则表达式入门
正则表达式(Regex)是一种用单个字符串来描述、匹配一系列符合特定语法规则的字符串的模式。它在文本编辑器和Linux工具(如 grep、sed、awk)中广泛用于文本检索和替换。
1. 常规匹配
不包含特殊字符的正则表达式会匹配它自身。
例如:grep "atguigu" filename 会匹配所有包含 “atguigu” 的行。
2. 常用特殊字符
| 字符 | 描述 | 示例 (用于 grep 或 awk) |
|---|---|---|
^ | 匹配一行的开头。 | grep "^start" file (匹配以 “start” 开头的行) |
$ | 匹配一行的结束。 | grep "end$" file (匹配以 “end” 结尾的行) |
. | 匹配任意一个单个字符(除了换行符)。 | grep "r..t" file (匹配 “root”, “r@@t” 等) |
* | 匹配前一个字符0次或多次。 | grep "ro*t" file (匹配 “rt”, “rot”, “root” 等) |
[] | 字符集,匹配方括号中任意一个字符。 | grep "gr[ae]y" file (匹配 “gray”, “grey”) |
[0-9] 匹配数字;[a-z] 匹配小写字母。 | grep "[0-9]" file (匹配含数字的行) | |
[^...] 否定字符集,匹配非括号内字符。 | grep "[^0-9]" file (匹配含非数字的行) | |
\ | 转义字符,用于匹配特殊字符本身。 | grep "a\\\$b" file (匹配 “a$b”) |
思考:
^$:匹配什么? 匹配空行。.*:匹配什么? 匹配任意数量的任意字符(通常是整行,因为.不匹配换行符,但*是贪婪匹配)。

3627

被折叠的 条评论
为什么被折叠?



