当前位置: 首页 > news >正文

正则表达式与文本三剑客grep、sed、awk

目录

一、正则表达式

1.1、字符匹配

1.2、次数匹配

1.3、位置锚定

1.4、分组或其他

二、扩展正则表达式

三、grep

四、awk

4.1、常用命令选项

4.2、工作原理

 4.3、基础用法

4.4、内置变量

4.5、模式

4.6、条件判断

4.7、awk中的循环语句

4.8、数组

4.9、脚本

五、sed

5.1、sed脚本格式

 5.2、sed命令

5.3、搜索替换

5.4、分组后向引用


一、正则表达式

正则表达式,又称规则表达式。(英语:Regular Expression),在代码中常简写为 regex、regexp 或 RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
正则表达式不只有一种,而且linux中不同的程序可能会使用不同的正则表达式,如:grep sed awk egrep 

LINUX 中常用的有两种正则表达式引擎:

  • 基础正则表达式:BRE
  • 扩展正则表达式: ERE

通配符与正则表达式的区别:

  • 通配符一般用于文件名匹配
  • 正则表达式一般用于匹配文件内容
1.1、字符匹配
元字符定义
.匹配除换行符\n之外的任意单个字符
[   ]匹配中括号内任意单个字符
[^ ]匹配除中括号内任意单个字符
[:alnum:]数字和字母
[:alpha:]任意大小写英文字符
[:lower:]小写字母
[:upper:]大写字母
[:blank:]空白字符(空格和制表符)
[:space:]空格、制表符、换行符、回车符等空白
[:cntrl:]不可打印的控制字符(退格、删除、警铃等)
[:digit:]十进制数字
[:xdigit:]十六进制数字
[:graph:]可打印的非空白字符
[:print:]可打印字符
[:punct:]标点符号
\w匹配单词 
\W
\s
\S
1.2、次数匹配
元字符定义
*匹配前面字符人任意次,包括0次
.*任意长度的任意字符,不包括0次
\?匹配前面字符出现0次或1次
\+前面字符出现最少1次
\{n\}匹配前面字符n次
\{m,n\}匹配前面字符最少m次,最多n次
\{,n\}匹配前面字符最多n次,≤n
\{n,\}匹配前面字符最少n次
1.3、位置锚定
元字符定义
^行首锚定,用于模式最左侧
$行尾锚定,用于模式最右侧
^PATTTERN$匹配整行
^$空行,不包括空格行
^[:space:]*$空白行
\b,\<词首锚定,用于模式最左侧
\b,\>词尾锚定,用于模式最右侧
1.4、分组或其他
元字符定义
(        )分组,将多个字符作为一个整体
(x\|y)由左向右匹配指定字符

二、扩展正则表达式

通常情况下会使用基础正则表达式就已经足够了,但有时为了简化整个指令,需要使用  范围更广的扩展正则表达式。

#次数匹配
*            #前面任意字符
?            #0或1次
+            #1次以上
{n}          #匹配n次
{m,n}        #最少m次,最多n次
{,n}         #前面字符最多n次,≤n
{n,}         #前面字符最少n次
#分组匹配
()           #多个字符当作整体处理
\1,\2,...    #向后引用
|            #或

三、grep

语法格式:grep 参数 文件名

常用参数:

-m<x>找到x行后停止查找
-v取反
-i忽略大小写
-n显示行号
-c统计行数
-o仅显示匹配到的字符
-q

静默模式,不输出任何信息

-A<x>显示匹配行,及之后的x行
-B显示匹配行,及之前的x行
-C显示匹配行,及前后x行
-e多个选项间的逻辑或
-E使用扩展正则表达式
-w只显示全字符合的列
-F不使用正则表达式
-f处理两个文件相同内容,以第一个文件为匹配条件
-r递归目录,不处理软链接
-R递归目录,处理软连接

--color=auto

高亮匹配字符

参考示例

#输出除之外的所有行 -v 选项
grep -v "match_pattern" file_name#标记匹配颜色 --color=auto 选项
grep "match_pattern" file_name --color=auto#使用正则表达式 -E 选项:
grep -E "[1-9]+"
egrep "[1-9]+"#选项 -e 制动多个匹配样式:
echo this is a text line | grep -e "is" -e "line" -o
is
is
line#在多级目录中对文本进行递归搜索:
grep "text" . -r -n
# .表示当前目录。#忽略匹配样式中的字符大小写:
echo "hello world" | grep -i "HELLO"
# hello

四、awk

awk命令来自三位创始人Alfred Aho、Peter Weinberger、Brian Kernighan的姓氏缩写,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。

它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。

语法格式:awk [选项] -f '脚本'/脚本文件 '模式{处理动作}'

4.1、常用命令选项
  • -F fs fs指定输入分隔符,fs可以是字符串或正则表达式,如-F:,默认的分隔符是连续的空格或制表符
  • -v var=value 赋值一个用户定义变量,将外部变量传递给awk
  • -f scripfile 从脚本文件中读取awk命令
  • -m[fr] val 对val值设置内在限制,-mf选项限制分配给val的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。
4.2、工作原理
  • 第一步:执行 BEGIN {commands} 语句块中的语句;
  • 第二步:从文件或标准输入(stdin)读取一行,然后执行 pattern {commands} 语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
  • 第三步:当读至输入流末尾时,执行 END {commands} 语句块。

BEGIN语句块:在awk开始从输入流中读取行 之前 被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中。

END语句块:在awk从输入流中读取完所有的行 之后 即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。

pattern语句块:中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{print},即打印每一个读取到的行,awk读取的每一行都会执行该语句块。

 4.3、基础用法

awk '模式{处理动作}'

#BGEIN{}模式
[root@localhost ~]# awk '{print}'
1
1
aabb
aabb
^C
[root@localhost ~]# awk '{print "aabb"}'
1
aabb#提取磁盘的分区利用率
[root@localhost ~]# df |awk '{print $5}'
已用%
0%
0%
2%
0%
80%
19%
1%
80%
0%#提取用户名和uid号
[root@localhost ~]# cat /etc/passwd |awk -F: '{print $1,$3}'
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
..............#提取ip地址
[root@localhost ~]# ifconfig ens33 |awk 'NR==2{print $2}'
192.168.153.23
4.4、内置变量
变量定义
FS字段分隔符(默认空格)
OFS输出字段分隔符(默认空格)
NF字段数,执行过程中对应当前字段数
NR记录数,执行过程中对应当前行号
$0当前处理的行的整行内容
$n当前处理行的第n个字段/列
FILENAME当前输入的文件名
RS记录分隔符(默认一个换行符)

参考示例

#FS变量的使用,-F优先级高于FS变量
[root@localhost ~]# awk -v "FS=:" '{print $1FS$3}' /etc/passwd
root:0
bin:1
daemon:2
[root@localhost ~]# awk -F: '{print $1":"$3}' /etc/passwd
root:0
bin:1
daemon:2#OFS变量的使用,替换分隔符
[root@localhost ~]# cat /etc/passwd|awk -v "OFS=--" -F: '{print $1,$3}'|head -n3
root--0
bin--1
daemon--2
[root@localhost ~]# cat /etc/passwd|awk -v "OFS=--" -v "FS=:" '{print $1,$3}'|head -n3
root--0
bin--1
daemon--2#RS变量的使用,替换分隔符为换行符
[root@localhost ~]# echo $PATH|awk -v "RS=:" '{print}'
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/root/bin#NF变量的使用,显示最后一列
[root@localhost ~]# df |awk '{print $NF}'
挂载点
/dev
/dev/shm
/run
/sys/fs/cgroup
/
/boot
/run/user/42
/var/lib/docker/overlay2/b3191762ed94dc8a583e6da75d8db197b583d63c7f925833df49e5b51e865a4f/merged
/run/user/0
[root@localhost ~]# df |awk '{print $(NF-1)}'
已用%
0%
0%
2%
0%
80%
19%
1%
80%
0%#NR变量的使用,匹配对应行
[root@localhost ~]# cat /etc/passwd |head -n3|awk '{print NR,$0}'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ~]# cat /etc/passwd|awk 'NR==1,NR==3{print NR,$0}'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ~]# cat /etc/passwd|head -n8|awk '(NR%2)==0{print NR,$0}'
2 bin:x:1:1:bin:/bin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
8 halt:x:7:0:halt:/sbin:/sbin/halt
4.5、模式

awk [选项] '模式{处理动作}'

#/正则表达式/:使用通配符的扩展集。
#匹配从root开头,ftp结尾的行
[root@localhost ~]# awk -F: '/^root/,/^ftp/{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
#仅匹配root开头,ftp开头的行
[root@localhost ~]# awk -F: '/^root/||/^ftp/{print $1,$3}' /etc/passwd
root 0
ftp 14
#关系表达式,使用运算符进行操作,可以是字符串或数字的比较测试
#n++表示不匹配第一行,即NR!=1
[root@localhost ~]# ss -natp|awk 'n++{print $1}'|sort|uniq -c1 ESTAB12 LISTEN
[root@localhost ~]# ss -natp|awk 'n++{a[$1]++}END{for(i in a){print a[i],i}}'
12 LISTEN
1 ESTAB[root@localhost ~]# seq 4|awk 'i=!i'
1
3
[root@localhost ~]# seq 4|awk '!(i=!i)'
2
4
[root@localhost ~]# seq 4|awk -v i=1 'i=!i'
2
4
4.6、条件判断

awk  选项   '模式 {条件|执行动作}' 

#过滤用户名及uid
[root@localhost ~]# cat /etc/passwd|awk -F: '{if($3>1000)print $1,$3}'
nfsnobody 65534
[root@localhost ~]# cat /etc/passwd|awk -F: '$3>1000{print $1,$3}'
nfsnobody 65534
[root@localhost ~]# cat /etc/passwd|awk -F: '{if($3>=uid){uid=$3;user=$1;sh=$NF}}END{print user,uid,sh}'
nfsnobody 65534 /sbin/nologin
4.7、awk中的循环语句
#for循环
#for(变量;条件;表达式){语句}
[root@localhost ~]# awk 'BEGIN{total=0;for(i=0;i<=100;i++){total+=i;}print total;}'
5050
4.8、数组

数组是awk的灵魂,处理文本中最不能少的就是它的数组处理。因为数组索引(下标)可以是数字和字符串在awk中数组叫做关联数组(associative arrays)。awk 中的数组不必提前声明,也不必声明大小。数组元素用0或空字符串来初始化,这根据上下文而定。

#得到数组长度
#length返回字符串以及数组长度,split进行分割字符串为数组,也会返回分割得到数组长度
[root@localhost ~]# awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print length(tA),lens;}'
4 4#输出数组内容
#无序输出
[root@localhost ~]# awk 'BEGIN{info="it is a test";split(info,tA," ");for(k in tA){print k,tA[k];}}'
4 test
1 it
2 is
3 a 
#有序输出
[root@localhost ~]# awk 'BEGIN{info="it is a test";tlen=split(info,tA," ");for(k=1;k<=tlen;k++){print k,tA[k];}}'
1 it
2 is
3 a
4 test
4.9、脚本

-f scripfile 从脚本文件中读取awk命令

[root@localhost opt]# vim asdf.txt
{if($3>=1000)print $1,$3}
[root@localhost opt]# awk -F: -f asdf.txt /etc/passwd
nfsnobody 65534
123123 1000

五、sed

stream editor的缩写,其功能是利用语法/脚本对文本文件进行批量的编辑操作。

它是文本处理中非常重要的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。

接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。

Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

语法格式:sed [选项] '命令' 文件名

常用参数:

-n就显示脚本处理后的结果
-e使用指定脚本处理输入的文本文件
-f使用指定脚本文件处理输入的文本文件
-r/-E支持扩展正则表达式
-i.bak直接修改文件内容而不输出到终端,并备份文件
[root@localhost opt]# sed -n -e '/^r/p'  -e'/^b/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
radvd:x:75:75:radvd user:/:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin[root@localhost opt]# sed -i.bak '1,4d' aaa  #删除第1,第4行
[root@localhost opt]# cat aaa
eeeee
fffff
ggggg
hhhhh
[root@localhost opt]# cat aaa.bak 
aaaaa
bbbbb
ccccc
ddddd
eeeee
fffff
ggggg
hhhhh
5.1、sed脚本格式
#范围匹配
[root@localhost opt]# seq 5|sed -n 'p'        #不指定范围则打印全文
1
2
3
4
5    
[root@localhost opt]# seq 5|sed -n '3p'       #打印第3行
3
[root@localhost opt]# seq 5|sed -n '1,3p'     #打印第1,第3行
1
2
3
[root@localhost opt]# seq 5|sed -n '1,+2p'    #打印第1行及后2行
1
2
3
[root@localhost opt]# seq 5|sed -n '1,2!p'    #取反
3
4
5
#步进
#打印第一行起,后每步进2打印一行,即奇数行
[root@localhost opt]# seq 10|sed -n '1~2p'
1
3
5
7
9
#打印第二行起,后每步进2打印一行,即偶数行
[root@localhost opt]# seq 10|sed -n '2~2p'
2
4
6
8
10
#第二行起,每三行步进打印
[root@localhost opt]# seq 10|sed -n '2~3p'
2
5
8
#第三行起,每三行步进打印
[root@localhost opt]# seq 10|sed -n '3~3p'
3
6
9
 5.2、sed命令
p打印模板块的行
q退出Sed
s替换指定字符
d删除,删除选择的行
a在当前行下面插入文本
i在指定行上面插入文本
c把选定的行改为新的文本
y把一个字符翻译为另外的字符
=打印当前行号
r从file中读行
w写并追加模板块到file末尾
!取反
#打印到第三行退出
[root@localhost ~]# cat /etc/passwd|sed '3q'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin#指定行后插入
[root@localhost ~]# seq 5|sed '2alook'
1
2
look
3
4
5
[root@localhost ~]# seq 5|sed '4alook\n eyes'
1
2
3
4
lookeyes
5
[root@localhost ~]# seq 5|sed '4alook\neyes'
1
2
3
4
look
eyes
5
[root@localhost ~]# seq 5|sed '3a   look'
1
2
3
look
4
5
[root@localhost ~]# seq 5|sed '3a\    look'
1
2
3look
4
5#指定行前插入
[root@localhost ~]# seq 5|sed '3i\    look'
1
2look
3
4
5
[root@localhost ~]# seq 5|sed '4ilook\neyes'
1
2
3
look
eyes
4
5#替换行
[root@localhost ~]# seq 5|sed '3c\    look'
1
2look
4
5
[root@localhost ~]# seq 5|sed '4clook\neyes'
1
2
3
look
eyes
5
5.3、搜索替换
替换标记定义
g行内全面替换
p打印行
w把行写入一个文件
x互换模板块中的文本和缓冲区中的文本
y把一个字符翻译为另外的字符
\1子串匹配标记
&已匹配字符串标记
基本格式 s/pattern/string/修饰符
#替换第二个.为@
[root@localhost opt]# sed 's/\./@/2' /etc/hosts
127.0@0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6@localdomain6#匹配字符后添加
[root@localhost opt]# sed -n 's/r..t/&er/gp' /etc/passwd
rooter:x:0:0:rooter:/rooter:/bin/bash
operator:x:11:0:operator:/rooter:/sbin/nologin
ftp:x:14:50:FTP User:/var/fterp:/sbin/nologin
5.4、分组后向引用
#提取ip地址
[root@localhost opt]# ifconfig ens33|sed -rn '2s/.*inet ([0-9.]+) .*/\1/p'
192.168.153.23#提取文件权限
[root@localhost opt]# stat aaa文件:"aaa"大小:24        	块:8          IO 块:4096   普通文件
设备:fd00h/64768d	Inode:18799731    硬链接:1
权限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
环境:unconfined_u:object_r:usr_t:s0
最近访问:2025-05-02 21:53:35.697373969 +0800
最近更改:2025-05-02 21:53:24.391268086 +0800
最近改动:2025-05-02 21:53:24.391268086 +0800
创建时间:-
[root@localhost opt]# stat aaa |sed -nr '4s/.*([0-9]{4}).*/\1/p'
0644
[root@localhost opt]# stat aaa|sed -n '4p'|egrep -o "[0-9]{4}"
0644
[root@localhost opt]# stat aaa|awk -F"[(/]" 'NR==4{print $2}'
0644

相关文章:

  • linux指令中的竖线(“|”)是干啥的?【含实例展示】
  • 数据库系统概论|第五章:数据库完整性—课程笔记1
  • 【服务器通信-socket】——int socket(int domain, int type, int protocol);
  • DBeaver连接人大金仓数据库V9
  • 上位机知识篇---PSRAM和RAM
  • 【算法基础】三指针排序算法 - JAVA
  • Google机器学习系列 - 监督学习
  • 50.【必备】二分答案法与相关题目
  • 玩转Docker(一):基本概念
  • STM32——GPIO
  • JAVA继承详细总结
  • MySQL 窗口函数
  • 解决Flutter项目中Gradle构建Running Gradle task ‘assembleDebug‘卡顿问题的终极指南
  • Ubuntu系统下Firefox浏览器完整指南:故障修复、国内版安装与下载加速
  • 如何封装一个线程安全、可复用的 HBase 查询模板
  • Midjourney 绘画 + AI 配音:组合玩法打造爆款短视频!
  • 模拟开发授权平台
  • Flutter BottomNavigationBar 详解
  • 定制开发开源AI智能名片S2B2C商城小程序驱动的无界零售基础设施变革研究——基于京东模式的技术解构与商业重构
  • 单链表操作(single list)
  • 出现这几个症状,说明你真的老了
  • 2025上海车展圆满闭幕,共接待海内外观众101万人次
  • 多地景区发公告称售票达接待峰值,有景区暂停网络和线下售票
  • A股2024年年报披露收官,四分之三公司盈利
  • 全球最大汽车板供应商宝钢股份:汽车工业加速转型中材料商如何共舞?
  • 美乌矿产协议签署被曝“临门一脚”时生变,美方提附加条件