sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
1.处理流程sed是一种流处理器,处理文本过程如下:
- 从文本或者管道中读入一行内容到模式空间(临时缓冲区)
- 使用sed命令处理,重复第一步,直到文件处理完毕
- 输出到屏幕
注意两点:
- sed 一次处理一行内容
- sed默认不改变文件内容
#命令行格式:将包含sed的命令写在命令行中执行 sed [options] 'command' file(s) #脚本格式:将sed的命令写在一个脚本中,然后执行的时候,指定sed脚本的路径即可 sed [options] -f scriptfile file(s)
options可以使用下面几个值:
-e : 可以指定多个命令 command
-n: 与p(print)命令合用时,表示只显示被选中的行,而不是(显示所有的行,然后被选中的行会显示两次)。
-i:将sed的操作结果更新到文件中,因为默认的是不会操作文件本身的。
command:行定位(正则)+ sed命令,首先会通过正则行定位,选中要进行操作的行,然后执行sed命令
测试数据(base) [root@localhost Tana]# cat -n data.txt 1 log1.txt female BeiJing 90 Yes 2 log2.txt male ShangHai 55 3 log3.txt male chengdu 66 china 4 log4.txt female shengzhen 33 china 5 log5.txt male guangdong 22 America 6 log6.txt female hongkong 11 Japan (base) [root@localhost Tana]#
选择1行,可以使用两种方式:
- n; 选中1行,n表示行号
- /pattern/ 使用正则表达式,注意要包含在/..../之间
- 打印第 6 行
(base) [root@localhost Tana]# sed -n '6 p' data.txt log6.txt female hongkong 11 Japan
- 打印匹配到 'female'的行
(base) [root@localhost Tana]# sed -n "/female/p" data.txt log1.txt female BeiJing 90 Yes log4.txt female shengzhen 33 china log6.txt female hongkong 11 Japan
选择多行,同样有两种方式:
- x,y; 选中行号在x~y之间的行
- /pattern1/, /pattern2/ 选择匹配两个正则表达式之间的行
- 打印第2~4 行
(base) [root@localhost Tana]# sed -n "2,4p" data.txt log2.txt male ShangHai 55 log3.txt male chengdu 66 china log4.txt female shengzhen 33 china
- 打印 Beijing 到chengdu之间的行
(base) [root@localhost Tana]# cat -n data.txt | sed -n "/BeiJing/,/chengdu/p" 1 log1.txt female BeiJing 90 Yes 2 log2.txt male ShangHai 55 3 log3.txt male chengdu 66 china
不选择某一行或者某几行
在后面加 ! 即可
- 打印除了第4行以外的所有行
(base) [root@localhost Tana]# sed -n "4! p" data.txt log1.txt female BeiJing 90 Yes log2.txt male ShangHai 55 log3.txt male chengdu 66 china log5.txt male guangdong 22 America log6.txt female hongkong 11 Japan
- 打印除2-5行之外的行
(base) [root@localhost Tana]# sed -n "2,5! p" data.txt log1.txt female BeiJing 90 Yes log6.txt female hongkong 11 Japan
间隔几行选择
使用x~y格式,首先打印第x行,然后每个y行,就打印一次
- 打印第一行,然后每隔2行打印
(base) [root@localhost Tana]# sed -n "1~2p" data.txt log1.txt female BeiJing 90 Yes log3.txt male chengdu 66 china log5.txt male guangdong 22 America
sed有几个基本的操作命令,分别是下面几个:
1、a (append,添加,在行后追加)
2、i(insert,插入,在行前插入)
3、d(delete,删除行)
4、c(chage,替换)
5、s(substitute,替换)
a 增加行
- 在第3 行后面增加一行
(base) [root@localhost Tana]# sed "3a ******** " data.txt log1.txt female BeiJing 90 Yes log2.txt male ShangHai 55 log3.txt male chengdu 66 china ******** log4.txt female shengzhen 33 china log5.txt male guangdong 22 America log6.txt female hongkong 11 Japan
- 在3~5 行 后面每一行增加 一行"====="
(base) [root@localhost Tana]# sed "3,5 a =========" data.txt log1.txt female BeiJing 90 Yes log2.txt male ShangHai 55 log3.txt male chengdu 66 china ========= log4.txt female shengzhen 33 china ========= log5.txt male guangdong 22 America ========= log6.txt female hongkong 11 Japan
i 插入行
i插入行和增加行的操作一样,区别是a是在行之后增加,i是在行之前插入
- 在3 ~5行前面每一行 插入一行 “========”
(base) [root@localhost Tana]# sed "3,5 i =====" data.txt log1.txt female BeiJing 90 Yes log2.txt male ShangHai 55 ===== log3.txt male chengdu 66 china ===== log4.txt female shengzhen 33 china ===== log5.txt male guangdong 22 America log6.txt female hongkong 11 Japan
c 替换行
替换行,是指,将指定行,整行内容都替换为指定内容,注意-s是指替换行中的一部分内容。注意,区间替换的时候,是整体替换,而不是逐行替换。
- 将每一行都替换为“hello world”
- (base) [root@localhost Tana]# sed"c hello" data.txt hello hello hello hello hello hello
- 试将第2~5行的每一行都替换为"hello world",但是实际操作后会将2-5行整体替换
(base) [root@localhost Tana]# sed "2,5c hello" data.txt
log1.txt female BeiJing 90 Yes
hello
log6.txt female hongkong 11 Japan
d 删除行
- 删除第4-6行
(base) [root@localhost Tana]# sed "4,6d" data.txt log1.txt female BeiJing 90 Yes log2.txt male ShangHai 55 log3.txt male chengdu 66 china
s 替换行的部分内容
- 将第3 行 字符a替换为uu,注意,在替换的时候,只替换了一次,即只替换第一个匹配的内容。如果要将满足条件的内容都替换,就需要加上g 。
这个和vim 的替换命令相同
(base) [root@localhost Tana]# sed "3 s/a/uu/g" data.txt log1.txt female BeiJing 90 Yes log2.txt male ShangHai 55 log3.txt muule chengdu 66 chinuu log4.txt female shengzhen 33 china log5.txt male guangdong 22 America log6.txt female hongkong 11 Japan
- 删除demo.txt文件中的空行
sed "/^$/ d"
2.获取eth0网卡的ip
(base) [root@localhost Tana]# ifconfig enp3s0f0 enp3s0f0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.23.57.159 netmask 255.255.255.0 broadcast 172.23.57.255 inet6 fe80::225:90ff:fefc:34d2 prefixlen 64 scopeid 0x20<link> ether 00:25:90:fc:34:d2 txqueuelen 1000 (Ethernet) RX packets 468531 bytes 40207603 (38.3 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 15880 bytes 2790713 (2.6 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device memory 0xfb120000-fb13ffff (base) [root@localhost Tana]# ifconfig enp3s0f0 |sed -n "/inet/p " inet 172.23.57.159 netmask 255.255.255.0 broadcast 172.23.57.255 inet6 fe80::225:90ff:fefc:34d2 prefixlen 64 scopeid 0x20<link> (base) [root@localhost Tana]# ifconfig enp3s0f0 |sed -n "/inet.* netmask/p " inet 172.23.57.159 netmask 255.255.255.0 broadcast 172.23.57.255 (base) [root@localhost Tana]# ifconfig enp3s0f0 |sed -n "/inet.* netmask/p " |sed "s/inet//" 172.23.57.159 netmask 255.255.255.0 broadcast 172.23.57.255 (base) [root@localhost Tana]# ifconfig enp3s0f0 |sed -n "/inet.* netmask/p " |sed "s/inet//"|sed "s/net.*$//" 172.23.57.159
包括以下内容:
1、{command1; command2; command 3}多个sed命令,使用“;”分开
2、n表示跳1行
3、&表示前面已经匹配的字符串内容,反向引用,不用再写一次正则表达式
多个sed命令
使用花括号{ }将多个sed命令包含在一起,多个sed之间用;分开 ,可以加也可以不加 { }
(base) [root@localhost Tana]# sed "3,5 d; s/male/Male/" data.txt log1.txt feMale BeiJing 90 Yes log2.txt Male ShangHai 55 log6.txt feMale hongkong 11 Japan
跳行
打印奇数行和偶数行
##打印奇数行
(base) [root@localhost Tana]# sed -n "1~2 p" data.txt log1.txt female BeiJing 90 Yes log3.txt male chengdu 66 china log5.txt male guangdong 22 America (base) [root@localhost Tana]# sed -n "{p;n}" data.txt log1.txt female BeiJing 90 Yes log3.txt male chengdu 66 china log5.txt male guangdong 22 America
##打印偶数行
(base) [root@localhost Tana]# sed -n "{n;p}" data.txt
log2.txt male ShangHai 55
log4.txt female shengzhen 33 china
log6.txt female hongkong 11 Japan
&反向引用
&表示前面已经匹配的字符串内容,反向引用,不用再写一次正则表达式
# 将 data.txt 里面的小写字母内容全部换成大写字母
(base) [root@localhost Tana]# sed "s/[a-z]/u&/g" data.txt LOG1.TXT FEMALE BEIJING 90 YES LOG2.TXT MALE SHANGHAI 55 LOG3.TXT MALE CHENGDU 66 CHINA LOG4.TXT FEMALE SHENGZHEN 33 CHINA LOG5.TXT MALE GUANGDONG 22 AMERICA LOG6.TXT FEMALE HONGKONG 11 JAPAN
# 把大写字母全部换成小写字母
(base) [root@localhost Tana]# sed " s/[A-Z]/l&/g" data.txt
log1.txt female beijing 90 yes
log2.txt male shanghai 55
log3.txt male chengdu 66 china
log4.txt female shengzhen 33 china
log5.txt male guangdong 22 america
log6.txt female hongkong 11 japan
r 复制指定文件插入到匹配行
# 将A.txt中的内容插入到B.txt中的第2行后面
sed '2 r A.txt' B.txt
#将A.txt中的内容插入到B.txt中包含CCCCCC的行后面
sed '/CCCCCC/ r A.txt' B.txt
#将A.txt中的内容插入B.txt中每一行的后面
sed 'r A.txt' B.txt
sed 替换命令
- a 在当前行下面插入文本。
- i 在当前行上面插入文本。
- c 把选定的行改为新的文本。
- d 删除,删除选择的行。
- D 删除模板块的第一行。
- s 替换指定字符
- h 拷贝模板块的内容到内存中的缓冲区。
- H 追加模板块的内容到内存中的缓冲区。
- g 获得内存缓冲区的内容,并替代当前模板块中的文本。
- G 获得内存缓冲区的内容,并追加到当前模板块文本的后面。
- l 列表不能打印字符的清单。
- n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
- N 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。
- p 打印模板块的行。
- P(大写) 打印模板块的第一行。
- q 退出Sed。
- b lable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾。
- r file 从file中读行。
- t label if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
- T label 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
- w file 写并追加模板块到file末尾。
- W file 写并追加模板块的第一行到file末尾。
- ! 表示后面的命令对所有没有被选定的行发生作用。
- = 打印当前行号码。
- # 把注释扩展到下一个换行符以前。
sed 替换标记
- g 表示行内全面替换。
- p 表示打印行。
- w 表示把行写入一个文件。
- x 表示互换模板块中的文本和缓冲区中的文本。
- y 表示把一个字符翻译为另外的字符(但是不用于正则表达式)
- 1 子串匹配标记
- & 已匹配字符串标记
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的行。