正则表达式
该笔记基于 shell
正则表达式是一种字符模式, 用于查找过程中匹配指定字符
[toc]
初次使用
例:
匹配 ^a
以 a 开头的字符
正则表达式可以被 vim
, sed
, awk
, grep
调用
1 2 3 4 5 6 7 8
| #双括号用于放正则表达式 #=~ 是正则表达式的开始(在判断语句中) if [[ $test =~ ^[0-9]+$ ]] #+$ 以一个或多个数字结尾 then echo "正确" else echo "错误" fi
|
基本正则表达式元字符
定义: 用于表达不同于字面本身含义的字符
被匹配文本示例: “ this is a great day.”
^
行首定位符
$
行尾定位符
.
匹配任意单个字符
*
匹配前导符 0 到多次
前导符, ab*
, b 为前导符
.*
匹配任意多个字符
[]
匹配指定范围内的一个字符
[-]
匹配指定连续范围内的一个字符
1 2
| #[a-Z] = [a-zA-Z] grep [a-z]his
|
[ ^ ]
匹配不在指定组内的字符
\
转义符
\<
词首定位符(不同于行首定位符)
\>
词尾定位符
()
匹配稍后使用的字符标签
1 2 3 4
| #例: #将shell脚本注释
:3,9 s/\(.*\)/#\1/ #\1 代表前方调用的括号
|
{}
前导符出现 n 次
字符出现指定次数才匹配
1 2 3 4 5
| grep m\{5\} #m出现5次
grep m\{5, \} #m出现5次以上
grep m\{5,10\} #m仅出现5~10次
|
扩展正则表达式元字符
egrep
才能识别扩展元字符
1 2 3 4
| egrep <扩展元字符>
# grep -E 等价于 egrep grep -E
|
+
匹配 1~n 个前导字符
?
匹配 0~1 个前导字符
a|b
匹配 a 或 b
()
组字符(用于组合匹配字符)
修饰符(待完善)
grep
1 2 3 4 5 6 7 8
| grep -v <字符> <文件> #匹配取反 grep -q <字符> <文件> #匹配静默(不显示匹配结果) grep <字符> -R <目录> #查找目录下的文件 grep -n #将行号显示出来
grep -B2 #同时显示匹配的前两行 -A2 #同时显示匹配的后两行 -C2 #同时显示匹配的上下两行
|
sed 流编辑器
用于 shell 编程更改文件内容(免交互)
1 2
| sed -r #使用正则表达式 sed -i #写入文件
|
实例:
不加入-i 选项, sed 只会写入缓存空间, 文件内容不会改变.
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
| sed -r "/<正则表达式>/<操作>/" <文件> sed -r "#<正则表达式>#<操作>#"
sed -r "/root/d" test.txt #删除匹配的字符行, d为操作(删除) sed -r "3d" test.txt #删除第3行字符 sed -r "3{d}" test.txt # {括号}内可以加多个选项 sed -r "3,6d" test.txt #删除3~6行字符 sed -r "d" #删除尾行
#替换文件字符 sed -r "s/替换前/替换后/" #替换字符(只换第一个) sed -r "s/替换前/替换后/g" #替换字符(全局替换) sed -r "s/替换前/&.5/" #调用匹配的字符, 结果为匹配字符后多了个.5 sed "s/(替换前)/\1.5/" #同上
#读取操作 sed -r "r test.txt" other.txt #读取目标文件字符并逐行打印 sed -r "5r test.txt" other.txt #在第5行输出指定文件字符 sed -r "/string/r test.txt" other.txt
#写入操作 sed -r "w test.txt" other.txt #other.txt的内容会传入test.txt sed -r "/string/w test.txt" other.txt ...
#追加操作 sed -r "a string" test.txt #逐行追加字符 sed -r '$a string' test.txt #在文件尾行传入字符
sed -r -e <操作1> -e <操作2> -e ... #-e选项用于多重编辑
|
操作字母 |
操作 |
操作字母 |
操作 |
d |
删除 |
w |
写入(另存为) |
i |
插入 |
a |
追加 |
s |
替换 |
c |
整行替换 |
& |
调用 |
n |
下一行 |
r |
读取其他文件 |
! |
取反 |
awk 切片
awk 切片技术
初识 awk
行: 记录(为$0
)
词: 字段(从第一个字段$1
开始, 以此类推$2
, $3
, $4
, …)
每过一行都会重置变量
1 2 3 4 5
| #对awk, $0是一行记录 awk '{print $0}' test.txt
#-F 指定记录分割符(可选) awk -F: #指定冒号":"为记录分隔符
|
awk 语法
1 2
| #常用语法 awk <选项> '<命令>' <文件>
|
awk 有三种执行时态:
- 开始
BEGIN{}
发生在行处理前(大小写敏感)
- 现在
{}
在行处理时, 读一行执行一次
- 结束
END{}
行处理后
1 2
| #例: awk 'BEGIN{print "行处理前: "} {print $1} END{print "行处理后"}' test.txt
|
内部变量
FS
输入字段分隔符(默认为空格)
OFS
输出字段分隔符
RS
输入记录分隔符(默认换行符)
FNR
多文件独立编号(类似行号)
NR
多文件汇总编号
NF
字段数
- . . . . . .
1 2 3 4 5 6
| #例: #以冒号为输入分隔符 awk 'BEGIN{FS=":"} {print $1}' test.txt
#输出分隔符(效果为插入指定的分隔符) awk 'BEGIN{FS=":"; OFS="666"} {print $1,$2,$3} END{}' test.txt
|
格式化输出
print 函数
1 2
| #例: date | awk '{print "当前年份: " $1, "\n当前月份:" $2}'
|
模式(正则表达式)和动作
awk 语句由模式和动作组成, 每一次处理都会有动作
模式常用正则表达式
1 2 3 4 5 6
| #例: #正则表达式模式 awk '/<正则表达式>/' <文件>
# ~ 代表字符串比较 awk '$0 ~/<正则表达式>/' test.txt
|
1 2 3 4 5
| #与多数编程语言的比较符相似 awk 'NR < 10' test.txt
#也可以进行运算 awk '{NR*2 < 10}' test.txt
|
1 2 3 4 5 6 7 8
| #例: #逻辑或和与(|| &&) awk '~/<正则表达式>/ && NR<=5' test.txt ...
#范围模式 #从第一个, 到第二个范围查找 awk '/<正则表达式>/, /正则表达式/' test.txt
|
awk 脚本编程
变量
1 2 3 4 5 6
| # "-v" 调用系统变量 #awk调用变量不需要"$" awk -v <引用变量> awk -v name=test '$1 == <变量名>' test.txt awk '$1 ~ "'"$name"'" ' test.txt #不介意使用
|
判断语句
1 2 3 4 5 6
| #if语句 if (<条件>) {<代码块>} ......#与C差不多
#例: awk '{if ($1 == id) {print "查询成功!"}}' test.txt
|
循环
有 for 和 while, 语句格式与 C 相似
数组
P36 待观看