1、简介
awk、grep、sed是linux操作文本的三大利器,合称文本三剑客。三者的功能都是处理文本,但侧重点各不相同,其中属awk功能最强大,但也最复杂。grep更适合单纯地查找或匹配文本;sed更适合编辑匹配到的文本,awk更适合格式化文本,对文本进行较复杂格式处理。
2、grep
2.1、什么是grep和egrep
Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并将匹配的行打印出来(匹配到的标红)。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。
grep的工作方式是这样的,它在一个或多个文件中搜索字符串模板。如果模板包括空格,则必须被引用,模板后的所有字符串被看做是文件名。搜索的结果被送到标准输出,不影响原文件内容。
grep可用于shell脚本,因为grep通过一个返回状态值来说明搜索的状态,如果模板搜索成功,则返回0;如果搜索不成功,则返回1;如果搜索的文件不存在,则返回2。可利用这些返回值进行一些自动化的文本处理工作。
egrep等同于grep -E:扩展的正则表达式(除了\<,\>,\b之外,使用其他正则都可以去掉\)
2.2、使用grep
2.2.1、命令格式
grep [option] pattern file
2.2.2、命令功能
用于过滤/搜索特定字符。可配合正则表达式来进行使用,使用上十分灵活。
2.2.3、命令参数
常用参数已加粗。
- -A<显示行数>:除了显示符合样式的那一行之外,并显示该行之后的内容。
- -B<显示行数>:除了显示符合样式的那一行之外,并显示该行之前的内容。
- -C<显示行数>:除了显示符合样式的那一行之外,并显示该行之前后的内容。
- -c:统计匹配的行数
- -e:实现多个选项间的逻辑or关系
- -E:扩展的正则表达式
- -f file:从file获取pattern匹配
- -F:相当于fgrep
- -i --ignore-case:忽略字符大小写的差别
- -n:显示匹配的行号
- -o:仅显示匹配到的字符串
- -q:静默模式,不输出任何信息
- -s:不显示错误信息
- -v:显示不被pattern匹配到的行,相当于[^]反向匹配
- -w:匹配整个单词
2.2.4、实战演示
# [root@docker test]# cat grep.txt aaa [root@docker test]# cat test aaa bbbbb AAAaaa BBBBASDABBDA #以grep.txt中每一行为关键字,查找test文件中匹配的行 [root@docker test]# grep -f grep.txt test aaa AAAaaa
3、正则表达式
3.1 分类
POSIX规范将正则表达式分为了两种
- 基本正则表达式(BRE,basic regular expression)
- 高级功能:扩展正则表达式(ERE,extended regular expression)
BRE和ERE的区别仅仅是元字符的不同
- BRE只承认的元字符有^$.[]*,其他字符识别为普通字符;
- ERE则添加了(){}?+|等
- 只用在用反斜杠“\”进行转义的情况下,字符串(){}才会在BRE被当做元字符处理,而在BRE中,任何元字符前面加上反斜杠反而会使其被当做普通字符来处理。
3.2、基本正则表达式
3.2.1、格式
字符 | 描述 |
---|---|
^ | ^word:搜索以word开头的内容 |
$ | word$:搜索以word结尾的内容 |
^$ | 表示空行,不是空格 |
. | 代表且只能代表任意一个字符(不匹配空行) |
\ | 转义字符,让有特殊含义的字符脱掉马甲,现出原形,如\.只表示小数点 |
* | 匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配 |
.* | 任意长度的任意字符,不包括0次 |
^.* | 以任意多个字符串开头,.*尽可能多,有多少算多少,贪婪性 |
[^abc] | 匹配不包含^后的任意字符a或b或c,是对[abc]的取反 |
a\ | 重复前面a字符至少n次,至多m次(如使用egrep或sed -r可去掉斜线) |
3.2.2、演练
3.3、扩展正则表达式
3.3.1、格式
特殊字符 | 描述 |
---|---|
+ | 重复前一个字符一次或多次 |
? | 重复前一个字符0次或1次(.是有且只有1个) |
| | 表示或,查找多个字符串 |
() | 分组过滤被括起来的东西表示一个整体(一个字符) |
3.3.2、演练
3.4、基本正则和扩展正则区别
所谓基础正则,实际上就是得需要转义字符配合表达的正则,而扩展正则就是让命令扩展它的权限让其直接就认识正则表达符号
BRE | ERE |
---|---|
? | ? |
\+ | + |
\ | {} |
\(\) | () |
\ |
3.5、补充说明
3.5.1、预定义
正则表达式 | 描述 | 示例 |
---|---|---|
[:alnum:] | [a-zA-Z0-9]匹配任意一个字母或数字字符 | [[:alnum:]]+ |
[:alpha:] | 匹配任意一个字母字符(包括大小写字母) | [[:alpha:]] |
[:blank:] | 空格与制表符(横向纵向) | [[:blank:]]* |
[:digit:] | 匹配任意一个数字字符 | [[:digit:]]? |
[:lower:] | 匹配小写字母 | [[:lower:]] |
[:upper:] | 匹配大写字母 | ([[:upper:]]+)? |
[:punct:] | 匹配标点符号 | [[:punct:]] |
[:space:] | 匹配一个包括换行符,回车等在内的所有空白符 | [[:space:]]+ |
[:graph:] | 匹配任何一个可以看得见的且可以打印的字符 | [[:graph:]] |
[:xdigit:] | 任何一个十六进制数 | [[:xdigit:]]+ |
[:cntrl:] | 任何一个控制字符(ASCII字符集中的前32个字符) | [[:cntrl:]] |
[:print:] | 任何一个可以打印的字符 | [[:print:]] |
3.5.2、元字符
元字符是一种Perl风格的正则表达式,只有一部分文本处理工具支持它,并不是所有的文本处理工具都支持。
正则表达式 | 描述 | 示例 |
---|---|---|
\b | 单词边界 | \bcool\b匹配cool,不匹配coolant |
\B | 非单词边界 | cool\B匹配coolant不匹配cool |
\d | 单个数字字符 | b\db匹配b2b,不匹配bcb |
\D | 单个非数字字符 | b\Db匹配bcb不匹配b2b |
\w | 单个单词字符(字母,数字与_) | \w匹配1或a,不匹配& |
\W | 单个非单词字符 | \W匹配&,不匹配1或a |
\n | 换行符 | \n匹配一个新行 |
\s | 单个空白字符 | x\sx匹配xx,不匹配xx |
\S | 单个非空白字符 | x\S\x匹配xkx,不匹配xx |
\r | 回车 | \r匹配回车 |
\t | 横向制表符 | \t匹配一个横向制表符 |
\v | 垂直制表符 | \v匹配一个垂直制表符 |
\f | 换页符 | \f匹配一个换页符 |
4、sed
4.1、认识sed
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下一行,执行下一个循环。如果没有使用诸如“D”的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非使用重定向存储输出或-i。
功能:主要用来自动编辑一个或多个文件,简化对文件的反复操作。
4.2、使用sed
4.2.1、命令格式
sed [选项] [command] 文件名
4.2.2、常用选项
- -n:不输出模式空间内容到屏幕,即不自动打印,只打印匹配到的行
- -e:多点编辑,对每行处理时,可以有多个script
- -f:把script写到文档中,在执行sed时,-f指定文件路径;如果有多个script,换行写入
- -r:支持扩展的正则表达式
- -i:直接将处理的结果写入文件
- -i.bak:在将处理的结果写入文件之前备份一份
4.2.3、地址定界
- 不给地址:对全文进行处理
- 单地址:
- #: 指定的行
- /pattern/:被此处模式所能够匹配到的每一行
- 地址范围:
- #,#
- #,+#
- /pat1/,/pat2/
- #,/pat1/
- ~:步进
- sed -n '1~2p' 只打印奇数行 (1~2 从第1行,一次加2行)
- sed -n '2~2p' 只打印偶数行
4.2.4、编辑命令
- d:删除模式空间匹配的行,并立即启用下一轮循环
- p:打印当前模式空间内容,追加到默认输出之后
- a:在指定行后面追加文本,支持使用\n实现多行追加
- i:在行前面插入文本,支持使用\n实现多行追加
- c:替换行为单行或多行文本,支持使用\n实现多行追加
- w:保存模式匹配的行至指定文件
- r:读取指定文件的文本至模式空间中匹配到的行后
- =:为模式空间中的行打印行号
- !:模式空间中匹配行取反处理
- s///:查找替换,支持使用其它分隔符,如:s@@@,s###;
- 加g表示行内全局替换;
- 在替换时,可以加一下命令,实现大小写转换
- \l:把下个字符转换成小写。
- \L:把replacement字母转换成小写,直到\U或\E出现。
- \u:把下个字符转换成大写。
- \U:把replacement字母转换成大写,直到\L或\E出现。
- \E:停止以\L或\U开始的大小写转换
4.3、演练
4.3.1、常用选项options
[root@aliyun shell]# cat demo aaa bbbb AABBCCDD [root@aliyun shell]# sed "/aaa/p" demo #匹配到的行会打印一遍,不匹配的行也会打印 aaa aaa bbbb AABBCCDD [root@aliyun shell]# sed -n "/aaa/p" demo #仅打印匹配的行,-n,不显示没匹配的行 aaa [root@aliyun shell]# sed -e "s/a/A/" -e "s/b/B" demo sed:-e 表达式 #2,字符 5:未终止的“s”命令 [root@aliyun shell]# sed -e "s/a/A/" -e "s/b/B/" demo #-e多点编辑 Aaa Bbbb AABBCCDD [root@aliyun shell]# cat sedscript.sed s/a/A/g [root@aliyun shell]# sed -f sedscript.sed demo #-f 使用文件处理 AAA bbbb AABBCCDD [root@aliyun shell]# sed -i.bak "s/a/A/g" demo #-i.bak直接对文本进行处理,同时将原文本备份为.bak文件 [root@aliyun shell]# cat demo AAA bbbb AABBCCDD [root@aliyun shell]# cat demo.bak aaa bbbb AABBCCDD
4.3.2、地址界定
[root@aliyun shell]# cat demo aaa bbbb AABBCCDD [root@aliyun shell]# sed -n "p" demo #不指定行,打印全部内容 aaa bbbb AABBCCDD [root@aliyun shell]# sed "2s/b/B/g" demo #替换第2行的b为B aaa BBBB AABBCCDD [root@aliyun shell]# sed -n "/aaa/p" demo aaa [root@aliyun shell]# sed -n "1,2p" demo #打印1-2行 aaa bbbb [root@aliyun shell]# sed -n "/aaa/,/DD/p" demo #打印aaa-DD行 aaa bbbb AABBCCDD [root@aliyun shell]# sed -n "2,/DD/p" demo #打印2-DD行 bbbb AABBCCDD [root@aliyun shell]# sed "1~2s/[aA]/E/g" demo #将奇数行的a或A替换为E EEE bbbb EEBBCCDD
4.3.3、编辑命令command
[root@aliyun shell]# cat demo aaa bbbb AABBCCDD [root@aliyun shell]# sed "2d" demo #删除第2行 aaa AABBCCDD [root@aliyun shell]# sed -n "2p" demo #打印第二行 bbbb [root@aliyun shell]# sed "2a123" demo #将123添加到第二行后面 aaa bbbb 123 AABBCCDD [root@aliyun shell]# sed "1i123" demo #将123添加到第一行前面 123 aaa bbbb AABBCCDD [root@aliyun shell]# sed "3c123\n456" demo #将123\n456替换第三行 aaa bbbb 123 456 [root@aliyun shell]# sed -n "3w/home/shell/demo3" demo #将第三行写到/home/shell/demo3文件中 [root@aliyun shell]# cat demo3 AABBCCDD [root@aliyun shell]# sed "1r/home/shell/demo3" demo #将/home/shell/demo3文件中内容读取到第一行后面 aaa AABBCCDD bbbb AABBCCDD [root@aliyun shell]# sed -n "=" demo #打印行号 1 2 3 [root@aliyun shell]# sed "s@[a-z]@\u&@g" demo #将所有小写字母转换为大写 AAA BBBB AABBCCDD [root@aliyun shell]# sed -n '2!p' demo #除第二行内容外,全部打印 aaa AABBCCDD
4.4、sed高级编辑命令
4.4.1、格式
- h:将模式空间中的内容覆盖至保持空间中
- H:将模式空间中的内容追加至保持空间中
- g:从保持空间取出数据覆盖至模式空间
- G:从保持空间取出数据追加至模式空间
- x:将模式空间中的内容与保持空间中的内容进行互换
- n:读取匹配到的行的下一行覆盖至模式空间
- N:读取匹配到的行的下一行追加至模式空间
- d:删除模式空间中的行
- D:删除当前模式空间开端到\n的内容(不再传至标准输出),放弃之后的命令,但是对剩余模式空间重新执行sed
4.4.2、案例+示意图
#倒叙输出文件内容 [root@aliyun shell]# cat num.txt 1 2 3 [root@aliyun shell]# sed '1!G;h;$!d' num.txt 3 2 1
示意图:
4.4.3、总结
保持空间是模式空间一个临时存放数据的缓冲区,协助模式空间进行数据处理
4.4.4、演练
#显示偶数行 [root@aliyun shell]# seq 9 | sed -n "n;p" 2 4 6 8 #倒叙显示 [root@aliyun shell]# seq 9 | sed '1!G;h;$!d' 9 8 7 6 5 4 3 2 1 #显示奇数行 [root@aliyun shell]# seq 9 | sed "H;n;d" 1 3 5 7 9 #打印最后一行 [root@aliyun shell]# seq 9 | sed "N;D" 9 #每行之间加空行 [root@aliyun shell]# seq 9 | sed "G" 1 2 3 4 5 6 7 8 9 #将每行内容替换成空行 [root@aliyun shell]# seq 9 | sed "g" #确保每一行下面都有一个空行 [root@aliyun shell]# seq 9 | sed '/^$/d;G' 1 2 3 4 5 6 7 8 9
5、awk
5.1、简介
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自于标准输入、一个或多个文件、或其他命令的输出。它支持用户自定义函数和动态正则表达式等功能,是linux/unix下的一个强大的编程工具。它在命令行中使用,但更多是作为脚本使用。awk有很多内建的功能,比如数组、函数等。
5.2、使用awk
5.2.1、语法
[root@localhost ~]# awk [选项] '脚本命令' 文件名
5.2.2、常用命令选项
- -F fs:指定以fs作为输入行的分隔符,awk命令默认分隔符为空格或制表符
- -v var=value:在执行处理过程之前,设置一个变量var,并给其设置初始值
- -f scriptfile:从脚本文件中读取awk命令,以取代直接在命令行中输入指令
awk的强大之处
awk的强大之处在于脚本命令,它由两部分组成,分别为匹配规则和执行命令,如下所示:
'匹配规则{执行命令}'
这里的匹配规则,用来指定脚本命令中可以作用到文本内容中的具体行,可以使用字符串(比如/demo/,表示查看含有demo字符串的行)或正则表达式指定。
注:整个脚本命令是用单引号括起来,而其中的执行命令部分需要用大括号括起来
5.3、awk变量
5.3.1、内置变量
变量 | 描述 |
---|---|
FS | 输入字符分隔符,默认为空白字符 |
OFS | 输出字段分隔符,默认为空白字符 |
RS | 输入记录分隔符,指定输入时的换行符,原换行符仍有效 |
ORS | 输出记录分隔符,输出时用指定符号代替换行符 |
NF | 字符数量,共有多少个字段,$NF引用最后一列,$(NF-1)引用倒数第二列 |
NR | 行号,后可跟多个文件,第二个文件行号则继续从第一个文件最后行号开始 |
FNR | 各文件分别计数,行号;后跟一个文件和NR一样,跟多个文件,第二个文件行号从1开始 |
FILENAME | 当前文件名 |
ARGC | 命令行参数的个数 |
ARGV | 数组,保存的是命令行所给定的各参数,查看参数 |
示例:
[root@aliyun shell]# cat awkdemo hello:world linux:redhat:lalala:hahaha along:love:you [root@aliyun shell]# awk -v FS=":" '{print $1,$2}' awkdemo #FS指定输入分隔符 hello world linux redhat along love [root@aliyun shell]# awk -v FS=":" -v OFS="---" '{print $1,$2}' awkdemo #OFS指定输出分隔符 hello---world linux---redhat along---love [root@aliyun shell]# awk -v RS=":" '{print $1,$2}' awkdemo hello world linux redhat lalala hahaha along love you [root@aliyun shell]# awk -v FS=":" -v ORS="---" '{print $1,$2}' awkdemo hello world---linux redhat---along love--- [root@aliyun shell]# awk -F: '{print NF}' awkdemo 2 4 3 [root@aliyun shell]# awk -F: '{print $(NF-1)}' awkdemo hello lalala love [root@aliyun shell]# awk END'{print NR}' awkdemo 3
5.3.2、自定义变量
1、先定义变量,后执行动作
[root@aliyun shell]# cat awkdemo hello:world linux:redhat:lalala:hahaha along:love:you [root@aliyun shell]# awk -v name="along" -F: '{print name":"$0}' awkdemo along:hello:world along:linux:redhat:lalala:hahaha along:along:love:you
2、先执行动作,后定义变量
[root@aliyun shell]# awk -F: '{print name":"$0;name="along"}' awkdemo :hello:world along:linux:redhat:lalala:hahaha along:along:love:you
3、调用脚本进行定义
[root@aliyun shell]# cat awk.txt {name="along";print name,$1} [root@aliyun shell]# awk -F: -f awk.txt awkdemo along hello along linux along along [root@aliyun shell]#
6、grep、sed、awk对比
- grep主要用于搜索某些字符串;sed和awk用于处理文本。
- grep基本是以行为单位处理文本的
- sed是一个非交互性文本流编辑器,它编辑文件或标准输入导出的文本拷贝。sed编辑器按照一次处理一行的方式来处理文件(或输入)并将输出送到屏幕上。sed把当前正在处理的行保存在一个临时缓存里,这个缓存叫做模式空间;一旦sed完成了对模式空间里的行的处理,就把模式空间的行送到屏幕上(除非该命令要删除该行或禁止打印);处理完该行之后,从模式空间中删除它,然后把下一行读入模式空间,进行处理并显示。当输入文件的最后一行处理完后,sed终止。通过将每一行存到一个临时缓存里并编辑该行,初始文件不会被修改或被破坏。
- awk和sed一样,也是逐行读取,是以字段为单位来处理文本
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了