目录
一.基本概念
1.1关于正则表达式
正则表达式(Regular Expression, RE)是一种字符模式, 用于在查找过程中匹配指定的字符. 在大多数程序里, 正则表达式都被置于两个正斜杠之间;
它将匹配被查找的行中任何位置出现的相同模式. 在正则表达式中,元字符是最重要的概念
元字符使正则表达式具有处理能力。所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。
Shell脚本通常使用grep
、sed
、awk
等工具来处理和匹配正则表达式。
二.基本元字符
2.1基本介绍
基本元字符是正则表达式中最基础的组成部分,掌握这些元字符对于编写高效的Shell脚本至关重要。以下是Shell脚本中正则表达式的基本元字符及其详细解释:
-
示例:.
:匹配任意单个字符。a.c #匹配 abc、a1c、a_c 等。
-
示例:^
:匹配字符串的开始位置。^hello #匹配以 hello 开头的字符串,如 hello world。
-
示例:$
:匹配字符串的结束位置。world$ #匹配以 world 结尾的字符串,如 hello world。
-
示例:+
:匹配前面的字符一次或多次(需要使用egrep
或grep -E
)。ab+c #匹配 abc、abbc、abbbc 等,但不匹配 ac。
-
示例:?
:匹配前面的字符零次或一次(需要使用egrep
或grep -E
)。ab?c #匹配 ac 或 abc。
-
示例:[]
:匹配方括号内的任意一个字符。[abc] #匹配 a、b 或 c。 [a-z] #匹配任意一个小写字母。
-
示例:[^]
:匹配不在方括号内的任意一个字符。[^abc] #匹配除了 a、b、c 之外的任意字符。 [^0-9] #匹配任意一个非数字字符。
-
示例:\
:转义字符,用于匹配特殊字符本身。\. #匹配点号。 \\ #匹配反斜杠。
三.拓展元字符
3.1拓展元字符介绍
-
示例:{n}
:匹配前面的字符恰好n
次。a{3} #匹配 aaa。
-
示例:{n,}
:匹配前面的字符至少n
次。a{3,} #匹配 aaa、aaaa、aaaaa 等。
-
示例:{n,m}
:匹配前面的字符至少n
次,但不超过m
次。a{3,5} #匹配 aaa、aaaa、aaaaa。
-
示例:|
:表示或操作,匹配两个或多个表达式中的一个。a|b #匹配 a 或 b。 (hello|world) #匹配 hello 或 world。
-
示例:()
:分组,用于将多个字符组合成一个整体。(abc)+ #匹配 abc、abcabc、abcabcabc 等。 (a|b)c #匹配 ac 或 bc。
四.grep语句
4.1基本了解
grep
是Shell脚本中一个非常强大的文本搜索工具,用于在文件中查找包含特定模式的行。grep
支持基本正则表达式(BRE)和扩展正则表达式(ERE),并且可以通过不同的选项来调整其行为。
grep
的基本语法如下:
grep [选项] 模式 [文件...]
- 模式:要搜索的正则表达式。
- 文件:要搜索的文件名,可以指定多个文件
常用选项
-i
:忽略大小写。
-v
:反向匹配,显示不包含模式的行。
-n
:显示匹配行的行号。
-c
:只显示匹配行的数量。
-r
:递归搜索目录下的所有文件。
-E
:使用扩展正则表达式(等同于 egrep
)。
-F
:固定字符串搜索(等同于 fgrep
),不解释正则表达式。
-l
:只显示包含匹配行的文件名。
-L
:只显示不包含匹配行的文件名。
-w
:匹配整个单词,而不是单词的一部分。
4.2grep基本正则表达式示例
# 匹配以 "hello" 开头的行
grep '^hello' file.txt
# 匹配以 "world" 结尾的行
grep 'world$' file.txt
# 匹配包含任意单个字符的行
grep 'a.c' file.txt
# 匹配包含连续三个数字的行
grep '[0-9]\{3\}' file.txt
4.3扩展正则表达式示例
# 使用扩展正则表达式,匹配包含 "hello" 或 "world" 的行
grep -E 'hello|world' file.txt
# 匹配包含连续三个或更多个数字的行
grep -E '[0-9]{3,}' file.txt
# 匹配包含 "abc" 重复一次或多次的行
grep -E '(abc)+' file.txt
五.sed语句
5.1基本介绍
sed
(Stream Editor)是一个强大的文本处理工具,广泛用于在Unix和Linux系统中进行文本替换、删除、插入等操作。它通常用于处理大文件或批量处理文本。
5.2sed
常用参数
-
不自动打印模式空间内容。通常和-n
p
命令结合使用,可以只打印某些行。 -
允许指定要执行的-e script
sed
脚本。可以使用多个-e
参数来执行多个命令。 -
从指定的文件中读取-f script-file
sed
脚本。 -
直接编辑文件内容(即对文件进行原地操作),可选地指定备份文件的后缀。-i[SUFFIX]
-
启用扩展的正则表达式语法。这种模式在一些系统中用-r
或--regexp-extended
-E
实现。 -
指定行的换行符长度为 N(BSD 版本下的选项)。-l N
5.3sed
的使用
sed
支持两种正则表达式语法:基本正则表达式 (BRE) 和扩展正则表达式 (ERE)。默认使用 BRE,如果使用 -r
或 -E
选项,则启用 ERE。
-
替换命令
s
sed 's/旧字符串/新字符串/' 文件
例如:
sed 's/foo/bar/' example.txt
将
example.txt
中的第一个foo
替换为bar
。 -
全局替换
sed 's/旧字符串/新字符串/g' 文件
例如:
sed 's/foo/bar/g' example.txt
将
example.txt
中的所有foo
替换为bar
。 -
删除命令
d
sed '/模式/d' 文件
例如:
sed '/foo/d' example.txt
删除
example.txt
中包含foo
的行。 -
打印命令
p
sed -n '/模式/p' 文件
例如:
sed -n '/foo/p' example.txt
打印
example.txt
中包含foo
的行。 -
插入和追加命令
i
和a
sed '/模式/i 新行' 文件 sed '/模式/a 新行' 文件
例如:
sed '/foo/i bar' example.txt
在包含
foo
的行前插入bar
。sed '/foo/a bar' example.txt
在包含
foo
的行后追加bar
。 -
替换行命令
c
sed '/模式/c 新行' 文件
例如:
sed '/foo/c bar' example.txt
将包含
foo
的行替换为bar
。
5.4sed高级用法
-
使用正则表达式
sed
支持使用正则表达式进行更复杂的匹配。例如:sed 's/[0-9]/X/g' example.txt
将
example.txt
中的所有数字替换为X
。 -
多命令执行 可以使用
-e
选项或分号;
来执行多个命令:sed -e 's/foo/bar/' -e 's/baz/qux/' example.txt
或
sed 's/foo/bar/; s/baz/qux/' example.txt
-
从文件读取命令 可以将命令写入文件,然后使用
-f
选项读取:sed -f commands.sed example.txt
示例:
假设有一个文件example.txt
内容如下:
foo bar
baz qux
foo baz
-
替换所有
foo
为bar
sed 's/foo/bar/g' example.txt
输出:
bar bar baz qux bar baz
-
删除包含
foo
的行sed '/foo/d' example.txt
输出:
baz qux
-
在包含
foo
的行前插入new line
sed '/foo/i new line' example.txt
输出:
new line foo bar baz qux new line foo baz
六.awk语句
6.1基本介绍
awk
是一种强大的文本处理工具,与 sed
一样,广泛用于数据提取与报告生成。awk
最显著的特点是它具有强大的模式匹配和内建的编程语言。
awk
基本语法
awk 'pattern { action }' filename
pattern
:匹配条件,决定在哪行上执行动作。{ action }
:在匹配的行上执行的动作。
awk工作原理
awk -F":" '{print $1,$3}' /etc/passwd
1.awk使用一行作为输入,并将这一行赋给变量$0,每一行可称作为一个记录,以换行符结束
2.然后,行被:分解成字段,每个字段存储在已编号的变量中,从$1开始
3.awk如何知道空格来分隔字段的呢?因为有一个内部变量FS来确定字段分隔符,初始时,FS赋为空格或者是tab
4.awk打印字段时,将以设置的方法,使用print函数打印,awk在打印的字段间加上空格,因为$1,$3间有一个,逗号。逗 号比较特殊,映射为另一个变量,成为输出字段分隔符OFS,OFS默认为空格
5.awk打印字段时,将从文件中获取每一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程持续到处理文件结束。
6.2常用变量与选项
常用选项
-F:指定字段分隔符。
-v:传递外部变量到 awk 程序中。
-f:从文件读取 awk 脚本。
awk
内置变量
$0:当前记录(整个行)。
$1, $2, ..., $n:当前记录的第 n 个字段。
FS:输入字段分隔符,默认为空格或 [ \t\n]+。
NF:当前记录的字段数。
NR:已经读出的记录数(行号)。
FNR:当前文件已经读出的记录数(对多文件处理有用)。
RS:输入的记录分隔符,默认为换行符。
OFS:输出字段分隔符。
ORS:输出记录分隔符。
6.3awk基本用法示例
-
打印文件的所有行
awk '{ print }' filename
-
打印特定列
awk '{ print $1, $3 }' filename
-
指定分隔符
awk -F ':' '{ print $1, $3 }' /etc/passwd
-
以模式匹配
awk '/pattern/ { print $0 }' filename
-
计算求和
awk '{ sum += $1 } END { print sum }' filename
6.4awk
正则表达式用法
awk
中支持多种正则表达式,用于模式匹配和字段处理。
1.正则表达式基本用法
-
匹配包含模式的行
awk '/pattern/' filename
-
过滤并打印 打印匹配特定模式的行:
awk '/^start/ { print }' filename # 打印以 "start" 开头的行
2.用正则表达式匹配字段
- 使用
~
(匹配) 和!~
(不匹配) 操作符awk '$1 ~ /^[A-Za-z]+$/ { print $0 }' filename # 第一列完全是字母的行
6.5awk
控制流语句
awk
也支持条件判断和循环,可以实现复杂的文本处理逻辑。
-
条件判断
awk '{ if ($1 > 100) print $0 }' filename
-
循环
awk '{ for (i = 1; i <= NF; i++) print $i }' filename
-
组合使用
awk '{ if ($1 > 100) { sum += $1; count++ } } END { if (count > 0) print sum/count }' filename
6.6综合示例
给定一个 data.txt
文件内容如下:
1 alice 2000
2 bob 1800
3 charlie 2500
4 david 3000
-
计算工资总和:
awk '{ sum += $3 } END { print "Total:", sum }' data.txt
-
打印工资大于2000的员工:
awk '$3 > 2000 { print $2, $3 }' data.txt
-
过滤名字以 'a' 开头的员工:
awk '$2 ~ /^a/ { print $0 }' data.txt
七.expect
7.1expect基础
expect
是一个用于自动化交互式脚本语言的工具,它基于 Tcl(Tool Command Language)并扩展了 Tcl 的功能,专门用来自动控制和操作那些依赖于交互(如需输入密码、确认等)的应用程序。
expect
的常见应用包括自动化SSH、FTP等网络服务的登录和操作、处理命令行交互式程序等。它通过预先编写的指令来模拟用户的交互,以实现在无人干预的情况下自动执行任务。
7.2基本概念与用法
expect
主要通过以下几个核心命令实现自动化交互:
-
spawn
:用于启动一个进程,类似于运行一个命令行。 -
expect
:等待进程输出特定内容,并捕捉和处理这些输出。 -
send
:向进程发送字符串,类似于键盘输入。 -
interact
:允许用户在expect
脚本中手动输入,与程序进行互动。
7.3典型的 expect
脚本结构
以下是一个典型的 expect
脚本结构:
#!/usr/bin/expect
# 设置超时时间
set timeout 10
# 启动一个进程
spawn ssh user@host
expect "password:"
# 发送密码
send "yourpassword\r"
# 如果需要,可以进一步处理交互内容
expect "$ "
send "ls -l\r"
# 结束交互,退出 shell
expect "$ "
send "exit\r"
# 交互结束
expect eof
7.4expect
关键命令详解
-
spawn
用于启动新的进程。 在脚本中使用 spawn command 来运行命令行程序。
-
expect
等待程序输出特定字符串。 基本语法为 expect "pattern",可以在匹配特定输出后执行指令。
-
send
发送字符串到被控制的进程中。 语法为 send "string\r","\r" 用于模拟回车键。
-
set timeout
设置 expect 的等待超时时间,单位为秒。 通常用于控制 expect 命令的等待时间。
-
interact
用于保持提示符状态,允许用户手动干预。 在脚本末尾加入 interact 可以让用户在自动化结束后接管会话。
7.5高级用法和技巧
1.处理多个可能的输出 使用 expect
的 -re
(正则表达式)来处理多个可能的输出:
expect {
-re "password:" { send "mypassword\r" }
-re "continue (yes/no)?" { send "yes\r"; exp_continue }
}
2.设置变量和传递参数 通过命令行参数传递变量参数:
#!/usr/bin/expect
set timeout 10
set user [lindex $argv 0]
set host [lindex $argv 1]
set password [lindex $argv 2]
spawn ssh $user@$host
expect "password:"
send "$password\r"
3.处理超时 使用 timeout
关键字来处理超时情况:
expect {
"password:" { send "mypassword\r" }
timeout { puts "Connection timed out."; exit 1 }
}
7.6综合示例
一个完整的 Expect 脚本来自动进行 FTP 登录并上传文件:
#!/usr/bin/expect
set timeout 30
set host "ftp.example.com"
set user "ftpuser"
set password "ftppassword"
set file "myfile.txt"
spawn ftp $host
expect "Name*:" { send "$user\r" }
expect "Password:" { send "$password\r" }
expect "ftp>" { send "put $file\r" }
expect "ftp>" { send "bye\r" }
expect eof
这个脚本模拟了一个 FTP 客户端的登录过程,自动输入用户名和密码,并上传一个文件,最后关闭连接。