linux那些事儿-文本三剑客
对于接触过Linux操作系统的人来说,应该都听过awk、grep、sed,它们是Linux下文本处理的三大利器,合称文本三剑客,也是必须掌握的linux命令之一。三者的功能都是处理文本,但侧重点各不相同,其中属awk功能最强大,但也最复杂。grep更适合单纯的查找或匹配文本,sed更适合编辑匹配到的文本,awk更适合格式化文本,对文本进行较复杂格式处理。文本三剑客均支持正则表达式,因此,在学习文本三剑客之前我们需要先来了解一下正则表达式。
正则表达式
又称规则表达式,是计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
许多程序设计语言都支持利用正则表达式进行字符串操作。正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开来的。
正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,该模式描述在搜索文本时要匹配的一个或多个字符串。
元字符 | 描述 |
---|---|
\ | 转义符 |
^ | ^word:搜索以word开头的内容 |
$ | word$:搜索以word结尾的内容 |
^$ | 空行 |
* | 匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配 |
.* | 任意长度的任意字符,不包括0次 |
.点 | 匹配除“\n”和”\r”之外的任何单个字符 |
| | 或运算,可匹配多个条件 |
文本三剑客之grep
grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
grep家族包括grep、egrep和fgrep。其中egrep是grep的扩展,支持更多的re元字符,fgrep则是fixed grep或fast grep。
用法
grep [选项] pattern file
其中:pattern代表被查找的字符,可以插入对应的元字符
选项
-c:只输出匹配行的计数。
-i:不区分大小写。
-h:查询多文件时不显示文件名。
-l:查询多文件时只输出包含匹配字符的文件名。
-n:显示匹配行及行号。
-s:不显示不存在或无匹配文本的错误信息。
-v:显示不包含匹配文本的所有行。
--color=auto :可以将找到的关键词部分加上颜色
-A:显示匹配的内容及其后n行
-B:显示匹配的内容及其前n行例如
[root@demo ~]# grep "cdrom" file
cdrom
[root@demo ~]# grep -i "cdrom" file
# Use CDROM installation media
cdrom
[root@demo ~]# grep -i -B2 -c "cdrom" file
2
[root@demo ~]# grep -i --color=none "cdrom" file
# Use CDROM installation media
cdrom
[root@demo ~]# grep -i -A1 "cdrom" file
# Use CDROM installation media
cdrom
# Keyboard layouts
[root@demo ~]# grep -i -B2 "cdrom" file
# Use graphical install
graphical
# Use CDROM installation media
cdrom
[root@demo ~]# grep -i -B2 -n "cdrom" file
9-# Use graphical install
10-graphical
11:# Use CDROM installation media
12:cdrom
文本三剑客之sed
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下一行,执行下一个循环。如果没有使用诸如“D”的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非使用重定向存储输出或-i。
用法
sed [选项] pattern file
其中,pattern部分涵盖被处理行的地址定界,以及对行的处理,如替换等
选项
-n:取消模式空间输出,转而输出匹配到的行,需要地址定界,通常组合编辑命令p进行打印输出。
-e:多个命令在处理文件时,将多个命令中指定的命令添加到运行的命令中。
-f:在处理文件时,将特定文件中指定的内容添加到运行的命令中,使文件做相应的修改。
-i:直接将处理的结果写入文件编辑
p:打印当前模式空间内容,追加到默认输出之后 a:在指定行后面追加文本,支持使用\n实现多行追加 i:在行前面插入文本,支持使用\n实现多行追加 c:替换行为单行或多行文本,支持使用\n实现多行追加 w:保存模式匹配的行至指定文件 r:读取指定文件的文本至模式空间中匹配到的行后 s///:查找替换,支持使用其它分隔符,如:s@@@,s###等,加g表示行内全局替换;
例如
[root@demo ~]# head -5 file
#version=RHEL8
ignoredisk --only-use=nvme0n1
autopart --type=lvm
# Partition clearing information
clearpart --none --initlabel
[root@demo ~]# sed -n '1p' file #p打印,1为行号,即为打印第一行
#version=RHEL8
[root@demo ~]# sed -n '1,5p' file #打印1-5行
#version=RHEL8
ignoredisk --only-use=nvme0n1
autopart --type=lvm
# Partition clearing information
clearpart --none --initlabel
[root@demo ~]# sed -n '1~2p' file #打印1行及后续步进为2的所有行,也就是奇数行打印。
#version=RHEL8
autopart --type=lvm
clearpart --none --initlabel
fod
# Use graphical install
# Use CDROM installation media
[root@demo ~]# sed '2a123' file #第二行后加入123
#version=RHEL8
ignoredisk --only-use=nvme0n1
123
[root@demo ~]# sed '1i123' file #第一行前加入123
123
#version=RHEL8
[root@demo ~]# sed -i '1i123' file #-i对原文件生效
[root@demo ~]# head -3 file
123
#version=RHEL8
ignoredisk --only-use=nvme0n1
[root@demo ~]# sed -e '1i123' -e '2a455' file #-e同时输入多个指令,在原第一行前加入123,在原第二行后边加入456
123
123
#version=RHEL8
455
[root@demo ~]# sed '2s/RHEL/rhel/' file #第2行RHEL替换为rhel
123
#version=rhel8
ignoredisk --only-use=nvme0n1
[root@demo ~]# cat txt
s/RHEL/rhel/g
[root@demo ~]# sed -f txt file #利用txt文件中的命令,完成全文的查找替换
123
#version=rhel8
ignoredisk --only-use=nvme0n1
autopart --type=lvm
[root@demo ~]# sed '1rtxt' file #将txt文件中的内容读到第一行后
123
s/RHEL/rhel/g
#version=RHEL8
文本三剑客之awk
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理,它更像是一门编程语言,支持条件判断、数组、循环等功能。
用法
awk [选项] pattern file
其中pattern主要包含两部分,匹配规则和执行命令,而awk最擅长的就是文本的格式化处理,所以最常见的动作就是print。
选项
-F:指定分隔符,awk命令默认分隔符为空格或制表符
-v:定义或者修改一个变量
-f:从脚本文件中读取awk命令内置变量
ARGC:命令行参数个数
ARGV:命令行参数排列
ENVIRON:支持队列中系统环境变量的使用
FILENAME:awk浏览的文件名
FNR:浏览文件的记录数
FS:设置输入字符分隔符,等价于命令行 -F选项
OFS:输出字符分隔符
NF:浏览记录的域的个数(几列)
NR:已读的记录数(几行)
ORS:输出记录分隔符
RS:输入记录分隔符
$0变量是指整条记录。$1表示当前行的第一个域,$2表示当前行的第二个域,......以此类推。例如
[root@demo ~]# cat file #分隔符为空格
hello linux hah
hello file
file process
[root@demo ~]# awk '{print $1}' file #打印file文件的第一列
hello
hello
file
[root@demo ~]# awk '{print $1,$2}' file #打印第一列和第二列
hello linux
hello file
file process
[root@demo ~]# awk -v "OFS=:" '{print $1,$2}' file #将输出字符分隔符替换为:
hello:linux
hello:file
file:process
[root@demo ~]# awk -F: '{print $1}' /etc/passwd #设置输入字符分隔符为:
root
bin
daemon
adm
lp
[root@demo ~]# awk '{print NR}' file #打印已读记录数
1
2
3
[root@demo ~]# awk '{print NF}' file #打印每个记录中列数
3
2
2
[root@demo ~]# awk '{print $(NF-1)}' file #打印倒数第二列
linux
hello
file
总结
三剑客各有应用场景,其中grep主要用于搜索字符串,sed主要用于文本的处理,而awk主要用于文本处理的格式化。
grep主要以行为单位处理,sed和awk逐行读取文件,以字段为单位处理文本。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1096485692@qq.com