开发者学堂课程【Shell 编程入门到精通:sed 和 awk 使用方法】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/453/detail/5605
sed 和 awk 使用方法
内容介绍
一、sed 使用
二、awk 使用
一、sed 使用
1.sed 定义
sed(strem editor)可称为线性编辑器或流编辑器。sed 编辑器是一行一行的处理文件内容的,特点是把正在处理的内容存放在模式空间(缓冲区)内,处理完成后按照选项的规定进行输出或文件的修改。
sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间”( pattern space ),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾,这里不像vim需要打开后才能进行修改。文件内容并没有改变,除非你使用重定向存储输出。Sed 主要用来自动编辑一个或多个文件,简化对文件的反复操作。
2.sed 语法
语法如下:
sed [options] ' [command]' [filename]
options:
-n抑制自动(默认的) 输出***读取下一个输入行
-e执行多个sed指令
-f运行脚本
-i编辑文件内容***
-i.bak编辑的同时创造.bak的备份
-r使用扩展的正则表达式***
command:
a 在匹配后追加***
I 在匹配后插入***
p打印***
d删除***
r/R读取文件/一行
w另存
s查找
c替换
y替换
h/H复制,拷贝/追加模式空间(缓冲区)到存放空间
g/G粘贴,从存放空间取回/追加到模式空间
x两个空间内容的交换
n/N拷贝/追加下一行内容到当前
D删除\n之前的内容
P打印\n之前的内容
b无条件跳转
t满足匹配后的跳转
T不满足匹配时跳转
3.案例
Ÿ 显示文件第三行
以前都是通过head或者tal显示前三行内容,如
[root@xuegod63 tmp]#
head
3
/
etc/passwd
[root@xuegod63 tmp]#
head
-n 3
/
etc/passwd
如果要显示第三行就要加-n,3p表示第三行,如
[root@xuegod63 tmp]# sed -n '3p' passwd
daemon:x:2:2:daemon:/ sbin:/ sbin/ nologin
Ÿ 显示文件前三行,如
[root@xuegod63 tmp]# sed -n '1,3p' passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/ sbin/ nologin
Ÿ 显示文件除前三行之外的全部内容,需要在p前!,如
[root@xuegod63 tmp]# sed -n '1,3
!
p' passwd
Ÿ 显示文件第三行和之后的三行
[root@xuegod63 tmp]# sed -n '3,+3p' passwd
Ÿ 在文件头插入“###”
命令为:sed首部在第一行,-i插入###,文件内部内容太多的话可以加上| more,表示不输出完整个文件。
[root@xuegod63 tmp]# sed '1
i
###' passwd > a.txt
Ÿ 在文件尾插入" @@@''
文件结尾用$表示,a表示进行追加,追加内容为@@@
[root@xuegod63 tmp]# sed '$a@@@' passwd > a.txt
Ÿ 把文件第三行替换成" $$$"
[root@xuegod63 tmp]# sed '3c$$$'
passwd
Ÿ 复制粘贴操作:把文件的第二行到第四行复制到文件的末尾,进行其他操作用;分隔,如下表示将2,4第二行到第四行内容进行拷贝到存放空间,再进行从存放空间粘贴到b.txt结尾。
[root@xuegod63 tmp]# sed '2,4H;$G' passwd > b.txt
h/H复制拷贝/追加模式空间(缓冲区)到存放空间
g/G粘贴从存放空间取回/追加到模式空间
4. sed 中的正则
sed中也有正则表达式,像常用的有^ $ . * 等都可以用。
例子:
Ÿ 删除空行 d 删除 ***
先grep查找空行位置,发现确实有空行在51行,如
[root@xuegod63 tmp]#
grep
^
$ passwd -n
51:
可以通过sed方式删除,先在以^开头$结尾中/匹配到空行,跟vim中的查找替换差不多,再执行动作为d删除,从passwd从定向输出到c.txt,如,
[root@xuegod63 tmp]# sed '/^$/d' passwd > c.txt
Ÿ 把fstab中包含ext4的记录(行)写入新的文件中,可通过grep过滤
[root@xuegod63 tmp]#
grep
ext
4 /etc/fstab
或sed查找内容ext4,再跟上动作w另存源newfstab2,set也可以,但set一般是查看系统环境变量,添加完后vim打开newfstab2可找到fstab中的内容,如,
[root@xuegod63 tmp]# sed '/ext4/ w newfstab2' /etc/fstab
或
[root@xuegod63 tmp]# se
d
'/ext4/ w newfstab' /etc/fstab
[root@xuegod63 tmp]#
vim
newfstab
2
UUID=ba5875b0- 6c75-4c2f-a312-eb12e2a733a8 /ext4
defaults
1 1
UUID=46cb104c-e4dc-4f84-8afc-552f21279c65 /boot ext4
defaults
1 2
~
~
[ root@xuegod63 tmp]# set |grep PATH
PATH=/usr/lib64/qt-3.3/bin: /usr/local/sbin: /usr/sbin:/sbin:
/usr/local/bin:/usr/bin:/bin: / root/bin
WINDOWPATH=1
二、awk 使用
1.awk 定义
AWK 是一种优良的文本处理工具,Linux 及 Unix 环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言(其名称得自于它的创始人阿尔佛雷德.艾侯、彼得.温伯格和布莱恩.柯林汉姓氏的首个字母)的最大功能取决于一个人所拥有的知识。最简单地说,AWK 是一种用于处理文本的编程语言工具。awk 命名:Alfred Aho Peter Weinberger 和 brian Kernighan 三个人的姓的缩写。
任何 awk 语句都是由模式和动作组成, 一个 awk 脚本可以有多个语句。模式决定动作语句的触发条件和触发时间。
特殊字段:
BEGIN 语句设置计数和打印头部信息,在任何动作之前进行。
END 语句输出统计结果,在完成动作之后执行。
awk中也可以使用正则表达式,分隔符默认是空格,可以用-F,改变成逗号为分隔符-F,或改成冒号-F:
安装软件方法:
[root@xuegod63 tmp]# rpm -qf which awk
gawk-3.1.7-6.el6.x86_ 64
[root@xuegod63 tmp]# rpm -qf which sed
sed-4.2.1-7.el6.x86_ 64
2.案例
(1)自定义年月日的显示方式
可通过data显示年月日,如,
[ root@xuegod63
tmp]# date
Wed Feb 11 21 :47 :57 CST 2015
但如果要自定义为Year:2015 month:Feb days:11形式显示,就需要使用awk,date后再| awk执行awk操作,单引号或双引号引起{ },{ }里写语句,print双引号打印year,:后取值,如上面$1表示第一列Wed,$2表示第二列Feb,以此类推表示Year年应该取值$6,\t表示table,month月取值$2,days天应该取值$3,注意像Year:,month:,days:等需打印内容应该用“”括起来:
[root@xuegod63 tmp]# date | awk '{print "Year:" $6 "\t month: "$2 "\t days: " $3"}'
Year:2015 month:Feb days:11
(2)显示所有内容
首先result.txt写入如下内容,
[root@xuegod63 tmp]#vim
result.txt
andy
4 85 92 78 94 88
bob
6 89 90 75 90 86
c
laire 9 84 88 80 92 84
d
ave 5 94 52 84 89 NA
一般都是通过awk进行列的操作,#awk '{print $0}' result.txt为显示result.txt全部内容,如
[root@xuegod63 tmp]#awk '{print $0}' result.txt
andy
4 85 92 78 94 88
bob
6 89 90 75 90 86
c
laire 9 84 88 80 92 84
d
ave 5 94 52 84 89 NA
$1表示显示第一列内容如下
[root@xuegod63 tmp]#awk '{print $1}' result.txt
andy
bob
c
laire
dave
(3)打印passwd第一列,因为passwd文件里面是以:做分隔符,没有空格,需要更改为-F:,如,
[root@xuegod63 tmp]# awk -F: '{ print $1 }' /etc/passwd
root
bin
daemon
…
(4)显示第一列和第三列的内容。用,分隔表示从第几列到第几列的操作,如
[root@xuegod63 tmp]# awk '{print $1,$3}' result.txt
name old
andy 85
bob 89
claire 84
dave 94
xuegod 1501
(5)打印一个文件头,打印一个文件尾
特殊字段:
BEGIN语句设置计数和打印头部信息,在任何动作之前进行。
END语句输出统计结果,在完成动作之后执行。
使用BEGIN在文件输出时表前打印头部,头部内容为name level result,END在文件输出后在表后打印尾部,尾部内容为end of class1 results ,andy作为name,4 为等级,85为得分,打印头部内容在前,表示在任何动作之前进行,中间是要打印文件中的内容,尾部是最后执行内容,三个语句都要在’ ’内,如,
[root@xuegod63 tmp]# awk '{
print
$1,$2,$3}’result.txt
andy 4 85
bob 6 89
claire 9 84
dave 5 94
[root@xuegod63 tmp]# awk 'BEGIN {print "name level result\n"} {print $1 ,$2,$3} END{ print
“
end of class1 results
“
}' result.txt
name level result
andy 4 85
bob 6 89
claire 9 84
dave 5 94
en
d
of
cIass1 resu
i
ts
(6)输出第二列大于等于5的记录,跟操作数据库类似。首先awk查找$2第二列大于等于5的记录,再print打印$0所有的记录。如,
[ root@xuegod63 tmp]# awk '$2 >= 5 {print $0}' result. txt
bob 6 89 90 75 90 86
c
laire 9 84 88 80 92 84
dave 5 94 52 84 86 NA
显示用户名为 andy 或(和)第二列为9的记录,’ ’里面写语句,if如果$1等于andy,||或者$2等于9,则输出所有记录,如,
[root@xuegod63 tmp]# awk '{ if($1 == "andy'll $2=="9') print $0 }' result.txt
andy
4 85 92 78 94 88
Claire 9 84 88 80 92 84
显示用户名为 andy 或(和)第二列为9的记录,因为文件里面没有符合这条件语句的记录,所以这里先向文件添加语句andy 9 84 88 80 92 84,查找命令为if如果满足$1等于andy或者$2等于9的条件,则打印全部记录,如,
[root@xuegod63 tmp]# awk '{ if($1 == "andy' && $2= ="9") print $0 }' result.txt
andy
9 84 88 80 92 84
如果需要$1等于andy并且$2等于9的记录,只要把||或改为&&与,如下:
[ root@xuegod63 tmp]# awk ' { if($1 == "andy" && $2=="9") print $0}'result. txt