文本处理三剑客之sed

时间:2022-07-22
本文章向大家介绍文本处理三剑客之sed,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

sed介绍:

  sed 全名为 stream editor,流编辑器,用程序的方式来编辑文本。sed 与vim等编辑器不同,sed 是一种非交互式编辑器(即用户不必参与编辑过程),它使用预先设定好的编辑指令对输入的文本进行编辑,完成之后再输出编辑结构。

sed工作原理:

 sed会一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,成为"模式空间",接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

sed用法:

       sed [option] ...'script' inputfile...                  (script是个动作,当单引号为空时,默认输出)

sed常用选项:

      -n:不输出模式空间内容到屏幕,即不自动打印

      -e:多点编辑

      -f: 从指定文件中读取编辑脚本

      -i.bak:备份文件并原处编辑

[root@CentOs7 ~]# cat 3.ttx 
root dcuduuhroot
rootbvnsn23rswt
rqqtjkkkkroot
r12tbcjnnjr13t
r11tmkcmkmkcscsdcvcmkmllkr11t

[root@CentOs7 ~]# cat 3.ttx | sed -n ' ' 
[root@CentOs7 ~]# cat 3.ttx | sed -n '2p' 
rootbvnsn23rswt
[root@CentOs7 ~]# cat 3.ttx | sed  -e 's/root/test/g' -e 's/cmkm/kobe/g' 
test dcuduuhtest
testbvnsn23rswt
rqqtjkkkktest
r12tbcjnnjr13t
r11tmkkobekcscsdcvkobellkr11t

[root@CentOs7 ~]# 

sed 地址定界:     (1) 不给地址:对全文进行处理     (2) 单地址:     #: 指定的行,$:最后一行     /pattern/:被此处模式所能够匹配到的每一行     (3) 地址范围:     #,#     #,+#     /pat1/,/pat2/     #,/pat1/     (4) ~:步进     1~2 奇数行     2~2 偶数行

[root@CentOs7 ~]# seq 10|sed -n '1~2p'
1
3
5
7
9
[root@CentOs7 ~]# seq 10|sed -n '2~2p'
2
4
6
8
10
[root@CentOs7 ~]# seq 10|sed -n '1~2!p'
2
4
6
8
10

sed常用命令:

a 在当前行下面插入文本。 i 在当前行上面插入文本。 d 删除,删除模式空间匹配的行,并立即启用下一轮循环。 s 替换指定字符 p 打印当前模式空间内容,追加到默认输出之后。 w 保存模式匹配的行至指定文件 r 读取指定文件的文本至模式空间中匹配到的行后。 ! 表示后面的命令对匹配行取反。 = 打印当前行号码。

[root@CentOs7 ~]# seq 3|sed '1ahello'
1
hello
2
3
[root@CentOs7 ~]# seq 3|sed '1ihello'
hello
1
2
3
[root@CentOs7 ~]# 
[root@CentOs7 ~]# seq 3|sed '2d'
1
3
[root@CentOs7 ~]# seq 3|sed 's/2/nihao/'
1
nihao
3
[root@CentOs7 ~]# seq 3|sed '2r/etc/fstab'
1
2

#
# /etc/fstab
# Created by anaconda on Tue Jul 10 12:01:36 2018
#
.......
[root@CentOs7 ~]# 

sed替换标记:

g 表示行内全面替换。 p 显示替换成功的行。 w 将替换成功的行保存至文件中。 1 子串匹配标记 & 已匹配字符串标记

[root@CentOs7 ~]# echo 1234567|sed  's/34/&AB/'   (匹配词34之后)
1234AB567
[root@CentOs7 ~]# echo 1234567|sed  's/67/CD&/'    (匹配词67之前)
12345CD67

sed元字符集:

^ 匹配行开始,如:/^sed/匹配所有以sed开头的行。 $ 匹配行结束,如:/sed$/匹配所有以sed结尾的行。 . 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。 * 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。 [] 匹配一个指定范围内的字符,如/[ss]ed/匹配sed和Sed。 [^] 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。 (..) 匹配子串,保存匹配的字符,如s/(love)able/1rs,loveable被替换成lovers。 & 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。 < 匹配单词的开始,如:/<love/匹配包含以love开头的单词的行。 > 匹配单词的结束,如/love>/匹配包含以love结尾的单词的行。 x{m} 重复字符x,m次,如:/0{5}/匹配包含5个0的行。 x{m,} 重复字符x,至少m次,如:/0{5,}/匹配至少有5个0的行。 x{m,n} 重复字符x,至少m次,不多于n次,如:/0{5,10}/匹配5~10个0的行。

[root@CentOs7 ~]# cat 3.ttx 
root dcuduuhroot
rootbvnsn23rswt
rqqtjkkkkroot
r12tbcjnnjr13t
r11tmkcmkmkcscsdcvcmkmllkr11t

[root@CentOs7 ~]# cat 3.ttx |sed -r 's/(r..t).*1/hello/g'
hello
rootbvnsn23rswt
rqqtjkkkkroot
r12tbcjnnjr13t
hello

[root@CentOs7 ~]# 

sed的高级用法----模式空间和保持空间

前面也有提到模式空间,即为处理文件中一行内容的一个临时缓冲区。处理完一行之后就会把模式空间中的内容打印到标准输出,然后自动清空缓存。

而这里说的保持空间是sed中的另外一个缓冲区,此缓冲区正如其名,不会自动清空,但也不会主动把此缓冲区中的内容打印到标准输出中。而是需要以下sed命令进行处理:

 保持空间sed在正常情况下,将处理的行读入模式空间,脚本中的“sed command(sed命令)”就一条接着一条进行处理,直到脚本执行完毕。然后该行被输出,模式被清空;接着,在重复执行刚才的动作,文件中的新的一行被读入,直到文件处理完毕。

模式空间可以比喻为一个生产线,而保持空间则可以被比喻为仓库。

h :把模式空间里的内容复制到暂存缓冲区(保持空间)

H :把模式空间里的内容追加到暂存缓冲区(保持空间)

g :把暂存缓冲区里的内容复制到模式空间,覆盖原有的内容

G:把暂存缓冲区的内容追加到模式空间里,追加在原有内容的后面

d: 删除pattern中的所有⾏行,并读入下一新行到P中

D:D 删除M ,P中的第一行,不读入下一行

n :读取下一个输入行,用下一个命令处理新的行而不是用第一个命令 N :追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码 具体用法如下:

seq 1 10 |sed 'n;d' 只显示奇数行

[root@CentOs7 ~]# seq 10|sed 'n;d'
1
3
5
7
9
[root@CentOs7 ~]# 

cat seq.txt |sed '/^$/d;G' 空行删除,每行后加一个空行,即保证每行后只有一个空行

[root@CentOs7 ~]# seq 10|sed '/^$/d;G'
1

2

3

4

5

6

7

8

9

10

seq 1 10 |sed 'g'  所有行变为空行

[root@CentOs7 ~]# seq 10|sed 'g'










[root@CentOs7 ~]#

seq 1 10 |sed '$!N;$!D' 输出倒数后两行

[root@CentOs7 ~]# seq 10|sed '$!N;$!D'
9
10
[root@CentOs7 ~]#

seq 1 10 |sed 'N;D' 或 seq 1 10 |sed '$!d' 只输出最后一行

[root@CentOs7 ~]# seq 10|sed 'N;D'
10
[root@CentOs7 ~]# seq 10|sed '$!d'
10

seq 1 10 |sed '1!G;h;$!d' 或 seq 1 10 |sed -n '1!G;h;$p' 倒序输出

[root@CentOs7 ~]# seq 10|sed '1!G;h;$!d'
10
9
8
7
6
5
4
3
2
1

seq 1 8 |sed -n 'n;p'  输出偶数行

[root@CentOs7 ~]# seq 10|sed -n 'n;p'
2
4
6
8
10
[root@CentOs7 ~]#