一、初识sed和gawk
初识sed和gawk
一、sed编辑器
sed编辑器被称作流编辑器(stream editor),不修改原文件,只将结果输出到STDOUT。
sed处理流程:
- 从一次输入中读取一行数据。
- 根据所提供的编辑器命令匹配数据。
- 按照命令修改流中的数据。
- 将新的数据输出到STDOUT。
sed的命令格式
格式: sed options script file
注释: sed 选项 脚本 文件
sed命令选项 | 描述 |
---|---|
-e script | 在处理输入时,将script中指定的命令添加到已有的命令中 |
-f file | 在处理输入时,将file中指定的命令添加到已有的命令中 |
-n | 不产生命令输出,使用print命令来完成输出 |
script参数指定了应用于流数据上的单个命令。如果要用多个命令,要么使用-e选项在命令行中指定,要么使用-f选项在单独的文件中指定。
1.在命令行定义编辑器命令
[root@nginx-120 ~]# echo "This is a test" | sed -e 's/test/big test/'
This is a big test
这个例子中使用了s命令,s命令会用斜线间指定的第二个文本字符串来替换第一个文本字符串。这里是用big test替换了test。
[root@nginx-120 ~]# cat data1.txt
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
[root@nginx-120 ~]# sed 's/dog/cat/' data1.txt
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
2.在命令行使用多个编辑器命令
要在sed命令上执行多个命令时,只要使用-e选项就可以。
[root@nginx-120 ~]# sed -e 's/brown/green/; s/dog/cat/' data1.txt
The quick green fox jumps over the lazy cat.
The quick green fox jumps over the lazy cat.
The quick green fox jumps over the lazy cat.
The quick green fox jumps over the lazy cat.
命令之间必须用分号隔开,并且在命令末尾和分号之间不能有空格。
如果不想用分号,也可以用bash shell中的次提示符来分隔命令。只要输入第一个单引号标示出sed程序的起始(sed编辑器命令列表),bash会继续提示你输入更多命令,直到输入了标示结束的单引号。
[root@nginx-120 ~]# sed -e '
> s/brown/green/
> s/fox/elephant/
> s/dog/cat/' data1.txt
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.
3.从文件中读取编辑器命令
[root@nginx-120 ~]# cat script1.sed
s/brown/green/
s/fox/elephant/
s/dog/cat/
[root@nginx-120 ~]# sed -f script1.sed data1.txt
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.
二、gawk程序
在所有发行版本中都没有默认安装gawk程序(centos7默认已安装),如若未安装请先安装。
gawk提供了一种编程语言而不只是编辑器命令,在gawk编程语言中,你可以做下面的事情:
- 定义变量来保存数据;
- 使用算数和字符串操作符来处理数据;
- 使用结构化编程概念(比如if-then语句和循环)来为数据处理增加处理逻辑;
- 通过提取数据文件中的数据元素,将其重新排列或格式化,生成格式化报告。
gawk程序的报告生成能力通常用来从大文本文件中提取数据元素,并将他们格式化成可读的报告。最常见的是格式化日志文件。
1.gawk命令格式
格式:gawk options program file
gewk选项 | 描述 |
---|---|
-F fs | 指定行中划分数据字段的字段分隔符 |
-f file | 从指定的文件中读取程序 |
-v var=value | 定义gawk程序中的一个变量及其默认值 |
-mf N | 指定要处理的数据文件中的最大字段数 |
-mr N | 指定数据文件中的最大数据行数 |
-W keyword | 指定gawk的兼容模式或警告等级 |
2.从命令行读取程序脚本
gawk程序脚本用一对花括号来定义。由于gawk命令行假定脚本是单个文本字符串,你还必须将脚本放到单引号中。
[root@nginx-120 ~]# gawk '{print "Hello World!"}'
这个程序脚本定义了一个命令:print命令,他将文本打印到STDOUT。如果尝试运行这个命令,会发现什么也没有发生。原因在于没有在命令行上指定文件名,所以gawk程序会从STDIN接收数据。在运行这个程序时,它会一直等待从STDIN输入的文本。
跟sed编辑器一样,gawk程序会针对数据流中的每行文本执行程序脚本。由于程序脚本被设为显示一行固定的文本字符串,因此不管在数据流中输入什么文本,都会得到同样的输出。
[root@nginx-120 ~]# gawk '{print "Hello World!"}'
This is a test
Hello World!
hello
Hello World!
要终止这个gawk程序,你必须表明数据流已经结束。bash shell提供了一个组合键来生成EOF(End-of-File)字符。Ctrl+D组合键会在bash中产生一个EOF字符。这个组合键能够终止改gawk程序并返回到命令提示符下。
3.使用数据字段变量
gawk的主要特性之一是其处理文本文件中数据的能力。他会自动给一行中的每个数据元素分配一个变量。默认情况下,gawk会将如下变量分配给他在文本行中发现的数据字段:
- $0代表整个文本行;
- $1代表文本行中的第1个数据字段;
- $2代表文本行中的第2个数据字段;
- $n代表文本行中的第n个数据字段;
在文本行中,每个数据字段都是通过字段分隔符划分的。gawk在读取一行文本时,会用预定义的字段分隔符划分每个数据字段。gawk中默认的字段分隔符是任意的空白字符(例如空格或制表符)。
在下面的例子中,gawk程序读取文本文件,只显示第1个数据字段的额值。
[root@nginx-120 ~]# cat data2.txt
One line of test text.
Two lines of test text.
Three lines of test text.
[root@nginx-120 ~]# gawk '{print $1}' data2.txt
One
Two
Three
如果你要读取采用了其他字段分隔符的文件,可以用-F选项指定。
[root@nginx-120 ~]# gawk -F: '{print $1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
4.在程序中使用多个命令
要在命令行上的程序脚本中使用多条命令,只要在命令之间放个分号即可。
[root@nginx-120 ~]# echo "My name is Rich" | gawk '{$4="Christine"; print $0}'
My name is Christine
第一条命令会给字段变量$4赋值,第二条命令会打印整个数据字段($0标示本行整个数据字段)
也可以用次提示符一次一行地输入程序脚本命令。
[root@nginx-120 ~]# gawk '{
> $4="Christine"
> print $0}'
My name is Rich
My name is Christine
按下Ctrl+D组合键来表明数据结束。
5.从文件中读取程序
[root@nginx-120 ~]# cat script2.gawk
{print $1 "'s home directory is " $6}
[root@nginx-120 ~]# gawk -F: -f script2.gawk /etc/passwd
root's home directory is /root
bin's home directory is /bin
daemon's home directory is /sbin
adm's home directory is /var/adm
lp's home directory is /var/spool/lpd
sync's home directory is /sbin
shutdown's home directory is /sbin
halt's home directory is /sbin
mail's home directory is /var/spool/mail
operator's home directory is /root
可以在程序文件中指定多条命令。只要一条命令放一行即可,不需要用分号。
[root@nginx-120 ~]# cat script3.gawk
{
text = "'s home directory is "
print $1 text $6
}
[root@nginx-120 ~]# gawk -F: -f script3.gawk /etc/passwd
root's home directory is /root
bin's home directory is /bin
daemon's home directory is /sbin
adm's home directory is /var/adm
lp's home directory is /var/spool/lpd
sync's home directory is /sbin
shutdown's home directory is /sbin
halt's home directory is /sbin
mail's home directory is /var/spool/mail
operator's home directory is /root
games's home directory is /usr/games
注意,gawk程序在引用变量值时并未像shell脚本一样使用美元符号。
6.在处理数据前运行脚本
默认情况下,gawk会从输入中读取一行文本,然后针对该行数据执行程序脚本。有时可能需要在处理数据前运行脚本,比如为报告创建标题。BEGIN关键字就是用来做这个的。他会强制gawk在读取数据前执行BEGIN关键字后指定的程序脚本。
[root@nginx-120 ~]# gawk 'BEGIN {print "Hello World!"}'
Hello World!
这次print命令会在读取数据前显示文本。但在显示了文本后,它会快速推出,不等待任何数据。如果想使用正常的程序脚本处理数据,必须用另一个脚本区域来定义程序。
[root@nginx-120 ~]# cat data3.txt
Line 1
Line 2
Line 3
[root@nginx-120 ~]# gawk 'BEGIN {print "The data3 File Contens:"} {print $0}' data3.txt
The data3 File Contens:
Line 1
Line 2
Line 3
7.在处理数据后运行脚本
与BEGIN关键字类似,END关键字允许你指定一个程序脚本,gawk会在读完数据后执行它。
[root@nginx-120 ~]# gawk 'BEGIN {print "The data3 File Contents:"} {print $0} END {print "End of File"}' data3.txt
The data3 File Contents:
Line 1
Line 2
Line 3
End of File
可以将所有这些内容放到一起组成一个漂亮的小程序脚本文件,用它从一个简单的数据文件中创建一份完整的报告。
[root@nginx-120 ~]# cat script4.gawk
BEGIN {
print "The latest list of users and shells"
print " UserID \t Shell"
print "--------- \t ---------"
FS=":"
}
{
print $1 " \t " $7
}
END {
print "This concludes the listing"
}
这个脚本中还定义了一个叫做FS的特殊变量。这是定义字段分隔符的另一种方法。这样就不用依靠脚本用户在命令行选项中定义字段分隔符了。
[root@nginx-120 ~]# gawk -f script4.gawk /etc/passwd
The latest list of users and shells
UserID Shell
--------- ---------
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin
This concludes the listing
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!