shell 正则表达式

First Post:

Last Update:

正则表达式

该笔记基于 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.”

^ 行首定位符

1
grep ^this

$ 行尾定位符

1
grep day$

. 匹配任意单个字符

1
grep d.y

* 匹配前导符 0 到多次

前导符, ab*, b 为前导符

1
grep gre*

.* 匹配任意多个字符

1
grep g.*t

[] 匹配指定范围内的一个字符

1
grep [t]his

[-] 匹配指定连续范围内的一个字符

1
2
#[a-Z] = [a-zA-Z]
grep [a-z]his

[ ^ ] 匹配不在指定组内的字符

1
grep [^0-9]his

\ 转义符

1
grep day\.

\< 词首定位符(不同于行首定位符)

1
grep \<this

\> 词尾定位符

1
grep day\>

() 匹配稍后使用的字符标签

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
  • () 组字符(用于组合匹配字符)
    1
    egrep "this(is|a)"

修饰符(待完善)


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 相似

数组

1
2
#定义:
<数组名>[下标]=<值>

P36 待观看