Sed
逐行进行处理数据。
sed:流编辑器,awk报告文本的生成器
sed基本用法:stream EDitor 对文本进行,逐行进行处理的行编辑器,还有一种全屏编辑器:例如vi,vim等
sed:模式空间
默认不直接处理源文件,仅对模式空间中的数据做处理,处理结束后,将 模式空间打印到屏幕。
它并直接处理文件的文本本身,它是需要处理的数据加载到内存当中,然后在内存中进项处理。然后这个内存空间叫做模式空间,说道模式,就应该会知道我们上次课说到的正则表达式,它就是按模式的,所谓模式就是按照一定的条件过滤一些内容,并不是全部进行处理的。
sed 常用参数
-e多条件编辑
-r 支持扩展正则表达式
-n 只显示匹配出的行
-f 指定sed脚本
-i 直接修改源文件
= 显示文件行号
使用行号,可以是一个简单数字,或是一个行号范围
x x为行号
x,y 表示行号从x到y
/pattern 查询包含模式的行
/pattern /pattern 查询包含两个模式的行
pattern/,x 在给定行号上查询包含模式的行
x,/pattern/ 通过行号和模式查询匹配的行
x,y! 查询不包含指定行号x和y的行
vim编辑一个test.txt
[root@sed ~]# cat test.txt
1
2
3
4
5
6
7
8
9
10
//打印文件中的第二行,默认会全部输出。加-n 选项,只打印匹配行
[root@sed ~]# sed '2p' test.txt
1
2
2
3
[root@sed ~]# sed -n '2p' test.txt
2
//取反
[root@sed ~]# sed -n '2!p' test.txt
//打印1到3行
[root@sed ~]# sed -n '1,3p' test.txt
先不说这些参数,直接先来说命令,既然是编辑,无非就几种操作,增、删、改、查,同样,我们再来用一个例子来说,
Vim编辑sed.txt
this is line 1,this is First line
this is line 2,the Second line,Empty line followed
this is line 4,this is Fourth line
this is line 5,this is Fifth line
1
2
3
4
5
this is line 5,this is Fifth line
6
You jump!
7
8
I jump!
9
10
删除命令
使用d命令可删除指定的行
例如:将文件的第一行删除后输出到屏幕
[root@sed ~]# sed '1d' sed.txt
this is line 2,the Second line,Empty line followed
this is line 4,this is Fourth line
this is line 5,this is Fifth line
//sed默认不修改原文件,如果希望保存修改后的文件则需要用重定向
[root@sed ~]# sed '1d' sed.txt > saved_file
[root@sed ~]# cat saved_file
//如果想直接修改文件,使用‘-i’参数
[root@sed ~]# sed -i '1d' saved_file
[root@sed ~]# cat saved_file
//删除指定范围的行(第1行到第3行)
[root@sed ~]# sed '1,3d' sed.txt
//删除指定行到下2行之间的内容,比如删除第3行到下两行之间的内容
[root@sed ~]# sed '3,+2d' sed.txt
//删除第3行到最后行
[root@sed ~]# sed '3,$d' sed.txt
//删除最后一行:
[root@sed ~]# sed '$d' sed.txt
[root@sed ~]# sed '$!d' sed.txt
//取反,加上!会把删除的内容打印出来
//跨奇数删除
[root@sed ~]# sed '1~2d' sed.txt
解释:从第一行开始,每隔两行删一次
//跨偶数删除
[root@sed ~]# sed '2~2d' sed.txt
或者[root@sed ~]# sed '1~2!d' sed.txt
从第3行开始,跨偶素数删除
[root@base tmp]# sed '3~2d' sed.txt
定点删除
定点删除的时候,如果知道行数,直接用行数删除了,不过大多数情况下都不知道行数,这个时候又改怎么做那?
//删除所有包含‘Empty’的行
[root@sed ~]# sed '/Empty/d' sed.txt
//删除所包含'Empty' 到最后的行
[root@sed ~]# sed '/Empty/,$d' sed.txt
//删除所包含'Empty' 到下两行的行
[root@sed ~]# sed '/Empty/,+2d' sed.txt
//删除从‘You jump!’ 到 “I jump‘ 的行,关键在于查找关键字
[root@sed ~]# sed '/^Y/,/^I/d' sed.txt
//删除空行
[root@sed ~]# sed '/^$/d' sed.txt
//这里注意标识空行,和含有空是有区别的
[root@sed ~]# sed '/[[:space:]]/d' sed.txt
查找替换(用到的最多)
使用s命令可将查找到的匹配文本内容替换为新的文本,默认情况只替换第一次匹配到的内容
[root@sed ~]# sed 's/line/LINE/' sed.txt
this is LINE 1,this is First line
this is LINE 2,the Second line,Empty line followed
如果想只替换第二个匹配到的line为LINE
[root@sed ~]# sed 's/line/LINE/2' sed.txt
this is line 1,this is First LINE
this is line 2,the Second LINE,Empty line followed
使用g选项,可以完成所有匹配值的替换
[root@sed ~]# sed 's/line/LINE/g' sed.txt
this is LINE 1,this is First LINE
this is LINE 2,the Second LINE,Empty LINE followed
s///,s@@@,s###,s&&&,等符号,都可以使用。
[root@sed ~]# sed 's@line@LINE@g' sed.txt
[root@sed ~]# sed 's&line&LINE&g' sed.txt
[root@sed ~]# sed 's#line#LINE#g' sed.txt
//将以this开头的this替换为that
[root@sed ~]# sed 's/^this/that/' sed.txt
that is line 1,this is First line
//将符合"," 换成"-"
[root@sed ~]# sed -n 's/,/-/gp' sed.txt
//思考如果删除每一行的第一个字符应该怎么做?
[root@sed ~]# sed 's/^.//g' sed.txt
解释:这个并不是把第一个字符删除,而是替换成空格
//在匹配到Empty的行,将行首第一个字母替换为*
[root@sed ~]# sed '/Empty/s/^./*/' sed.txt
//在匹配到Empty的行,行首的单词前添加you can see
[root@sed ~]# sed '/Empty/s/^/you can see/' sed.txt
字符转换
使用y命令可以进行字符转换,其作用为将一系列字符逐个地变换为另外一系列字符,基本用法如下:
注意转换字符和被转换字符的长度要相等,否则sed无法执行
sed 'y/OLD/NEW/' file
[root@sed ~]# sed 'y/1245/ABCD/' sed.txt
//需要注意的是,它会查找每行内所有匹配到的字符,逐个对应进行替换
插入文本
使用i或a命令插入文本,其中i代表在匹配行之前插入,而a代表在匹配行之后插入,示例如下:
//使用i在第二行前插入文本
[root@sed ~]# sed '2 i Insert' sed.txt
//使用a在第二行后插入文本
[root@sed ~]# sed '2 a append' sed.txt
//在匹配行的上一行插入文本
[root@sed ~]# sed '/Second/i\Insert' sed.txt
//在匹配行的下一行插入文本
[root@sed ~]# sed '/Second/a\Insert' sed.txt
//如果要同时新增多行,则每行之间要用反斜杠\n来进行新行的添加
[root@sed ~]# sed '2 a\append1\nappend2\nappend3' sed.txt
this is line 1,this is First line
this is line 2,the Second line,Empty line followed
append1
append2
append3
//在匹配到how的句子后面添加一句:I'm fine.
[root@sed ~]# sed "/how/s/$/ I'm fine/" sed.txt
注意单双引号
//如果添加双引号那?
[root@sed ~]# sed '/how/aI"m fine.' sed.txt
如果sed 框架的 单引号 或者双引号 ,和要输出的内容有冲突 ,就需要对它进行转义然后再次隐起来
[root@sed ~]# sed '/how/s/$/ I'\''fine/' sed.txt
取代行
c命令,c的后面可以接字符串,这些字符串可以取代n1,n2之间的行
[root@sed ~]# sed '2,4c this is 2-4 line' sed.txt
1 this is line 1,this is First line
2 this is 2-4 line
5 this is line 5,this is Fifth line
读入文本
使用r命令可从其他文件中读取文本,并插入匹配行之后,
例如:
将/etc/passwd中的内容读出放到Sed.txt空行之后
[root@sed ~]# sed '/^$/r /etc/passwd' sed.txt
将/etc/passwd中的内容读出放到Sed.txt末尾之后
[root@sed ~]# sed '$ r /etc/passwd' sed.txt
打印
使用p命令可进行打印,这里使用sed命令时一般都加-n参数,表示不打印没关系的行。
不加-n参数,会输出所有行,找到的行会重复显示
[root@sed ~]# sed -n '/the/p' sed.txt
//当用到sed不同的编辑命令时,可以用{ },不同的编辑命令之间用分号隔开
[root@sed ~]# sed -n "/the/{=;p}" sed.txt
2 //”=” 是显示行号
this is line 2,the Second line,Empty line followed
//打印前5行
[root@sed ~]# sed '5q' sed.txt
//打印出匹配first的行到第4行
[root@sed ~]# sed -n '/First/,4p' sed.txt
//打印出不包含line的行
[root@sed ~]# sed -n '/line/!p' sed.txt
sed脚本
使用sed脚本可以加快工作效率,调用sed命令并使用-f参数指定件
写如下脚本,作用是将全文的this改成THAT,并删除所有空行
Vim 编辑sed01.txt
s/this/THAT/g
/^$/d
y/1245/ABCD/
[root@sed ~]# cat sed01.txt
//执行sed脚本
[root@sed ~]# sed -f sed01.txt sed.txt
也可以这样写脚本:
[root@sed ~]# cat > sed02.txt <<EOF
\> #!/usr/bin/sed -f
\> s/this/THAT/g
\> /^$/d
\> y/1245/ABCD/
\> EOF
[root@sed ~]# cat sed02.txt
[root@sed ~]# chmod +x sed02.txt
[root@sed ~]# ./sed02.txt sed.txt
//如果按照此脚本的要求: 将全文的this改成THAT,并删除所有空行.改写为一条sed语句,应该怎么做?
[root@base ~]# sed -e 's/this/that/g' -e '/^$/d' sed.txt
或者
[root@base ~]# sed 's/this/that/g; /^$/d' sed.txt
sed 总结
sed 默认不对原文件执行操作,如果向生效,则使用-i,而且默认全部
打印输出,如果想只打印匹配到的行,用p,前面加上-n 参数。
删除:d,定点删除,从哪里到哪里删除,删除开头,结尾等。跨奇数、
偶数删除、包括单词的行删除、
查找替换: s///,s@@@,s###,s&&&,等符号,都可以使用。
字符转换:y/// 但注意的是,新的字符必须和旧的字符长度相同,否则无法使用。
插入文本: i insert: 匹配行前边,
a append: 匹配行后边。
添加多行,注意使用\n 换行符。
取代行:选择到几行到几行之后, 然后用c 后面就可以用一句话代替
sed中常用的符号解释:
\u : 就是表示把第一个字符转化成大写字母。uppercase
\l : 表示小写
& : 就是表示匹配前面正则表达式的那部分
\b : 匹配一个单词边界,也就是指单词和空格间的位置
练习
1、删除/etc/grub2.cfg文件中所有以空白开头的行,思考如果向要删除这些空白字符应该怎么做?
[root@sed ~]# sed '/^[[:space:]]/d' /etc/grub2.cfg
直接将空白开头那一行删除
[root@sed ~]# sed 's/^[[:space:]]//g' /etc/grub2.cfg
只删第一个空格
2、删除/etc/fstab文件中所有以#开头
[root@sed ~]# sed '/^#/d' /etc/fstab
3、将/etc/fstab中全部添加#号键,并以#号开头
[root@sed ~]# sed 's/^/\#/g' /etc/fstab
4、删除/etc/passwd中的偶数行
[root@sed ~]# sed '2~2d' /etc/passwd
5、从/etc/passwd中找出包含root的行,并把root改成rooter
[root@sed ~]# sed 's/root/rooter/g' /etc/passwd
将替换的打印出来
[root@sed ~]# sed -n 's/root/rooter/gp' /etc/passwd
rooter:x:0:0:rooter:/rooter:/bin/bash
operator:x:11:0:operator:/rooter:/sbin/nologin
6、从/etc/passwd中找到以为bash结尾并在这些行后面加上一句话:you are very good!
[root@sed ~]# sed '/bash$/a you are very good!'
/etc/passwd
7、删除/etc/passwd中头三行信息,
[root@sed ~]# sed '1,3d' /etc/passwd
[root@sed ~]# sed -n '4,$p' /etc/passwd
8、只打印/etc/passwd中第5到第10行信息。
[root@sed ~]# sed -n '5,10p' /etc/passwd
9、删除/etc/passwd中,包含'ftp‘的行到包好'ntp'的行
[root@sed ~]# sed '/ftp/,/ntp/d' /etc/passwd
10、删除所有包含nologin的行
[root@sed ~]# sed '/nologin/d' /etc/passwd
11、将所有的bin,改成sbin
[root@sed ~]# sed 's/bin/sbin/g' /etc/passwd
12、用how are you 取代包含usr的行
[root@sed ~]# sed -n '/usr/c how are you' /etc/passwd
13、把包含数字的换成*号代替
[root@sed ~]# sed 's/[[:digit:]]/*/g' /etc/passwd
14、把包含sync的行,到包含sshd的行 全部用 Come on 代替!
[root@sed ~]# sed '/sync/,/sshd/c Come on' /etc/passwd
15、把每个单词的第一个小写字母变大写。
[root@sed ~]# sed 's/\<[a-z]/\u&/' /etc/passwd
16、匹配以字母a开头的行尾位加上一句话:To be NO.1
[root@sed ~]# sed -r 's/(^a.*)/\1 To be NO.1/' /etc/passwd
17、找出包含nobody的行,打印出,并只打印匹配的内容
[root@sed ~]# sed -n '/nobody/{p;=}' /etc/passwd
nobody:x:99:99:Nobody:/:/sbin/nologin
13
nfsnobody:x:65534:65534:Anonymous NFS
User:/var/lib/nfs:/sbin/nologin
30
18、只打印从包含gnome到最后 的行
[root@sed ~]# sed -n '/gnome/,$p' /etc/passwd
19、同时打印以mail开头的行和以rpm开头的行
[root@sed ~]# sed -n -e '/^mail/p' -e '/^rpc/p'
/etc/passwd
或者
[root@sed ~]# sed -n ‘/^mail/p; /^rpc/p’ /etc/passwd
20、从第5行开始到结束把:符号换成*符号
[root@sed ~]# sed '5,$s/:/*/g' /etc/passwd
21、打印出前10行
[root@sed ~]# sed '10q' /etc/passwd
22、从/etc/fstab文件中,打印出不包含##的行
[root@sed ~]# sed -n '/#/!p' /etc/fstab
23、将第8行,到匹配到行首为gdm的行首第一次字母替换为*
[root@sed ~]# sed '8,/gdm/s/^./*/g' /etc/passwd
24、在匹配以sshd开头的行后面添加两行内容,分别为:are you ok?
yes, I'm fine.
[root@sed ~]# sed '/sshd/a are you ok?\nyes,I'\''m fine!'
/etc/passwd