sed
1、概述
.
- 核心功能:取行、过滤、替换修改文件内容
- 难点:后向引用(截取)
- sed stream editor(流式编辑器)
2、命令格式
-
命令格式1:前置命令 | sed [选项] '[指令]' 文件名
-
命令格式2:sed [选项] '[指令]' 文件名
参数 | 含义 |
---|---|
-n | 屏蔽默认输出,默认sed会将所有的输出结果输出到屏幕中,-n只把sed处理的行输出到屏幕 如果不使用-n参数,那么输出的内容会输出两遍,也就是说-n屏蔽的是sed -p的默认输出 |
-i | 直接修改文件内容,如果不加-i选项,并不会真正改变文件的内容 |
-r | 使用扩展正则,若与其他选项一起使用,此选项应该在首位 |
-i.bak | 修改文件内容之前先进行备份,然后再修改内容(一般用于替换一个文件),这个参数要放在所有参数的最后面 |
3、执行流程
sed 的工作流程
读取:sed从输入流(文件、管道、stdin)中读取一行内容并保存到临时文件缓冲区中(又称模式空间:pattern space)
执行:默认情况下,所有的sed命令都在模式空间中顺序地执行,除非制定了行的地址,否则sed命令将会在所有命令行上依次执行
显示:发送修改后的内容到输出流,在发送数据后,模式空间(pattern space)将会被清除
在所有的文件内容都被处理完成之前,上述过程将会重复执行,直至所有的内容被处理完成
在默认情况下,所有的sed命令都是在pattern space中完成的,因此输入的文件不会有任何变化,除非是用重定向存储输出
4、sed查找
一种是类似于grep的模糊查找(正则查询)
类似于grep命令的过滤,比grep强在可以指定行号
一种是精确查找,行号
(1)、取出文件的第3行
-n:取消默认输出,sed在处理文件的时候会默认的输出每一行的内容
p:表示输出,一般和-n搭配使用
[root@Ansible-server opt]# sed -n '3p' a.txt
goooood
(2)、取出2到5行
[root@Ansible-server opt]# sed -n '2,5p' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
(3)、取出2行和5行
[root@Ansible-server opt]# sed -n '2p;5p' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
(4)、过滤出包含root的行
⚠️sed支持过滤某一个内容
/内容/p,打印出过滤的内容
sed支持正则,默认是支持基础正则
-r参数可以让其支持扩展正则
[root@Ansible-server opt]# sed -n '/root/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
stap-server:x:155:155:Systemtap Compile Server:/opt/rh/gcc-toolset-11/root/var/lib/stap-server:/sbin/nologin
[root@Ansible-server opt]# sed -n '/^root/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@Ansible-server opt]# sed -r -n '/^(root|bin)/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
(5)、模拟过滤日志
[root@Ansible-server log]# cat sed.txt
101,xiaoxu,ccc
102,xiaoli,bbb
103,xiaowang,ddd
104.xiaozhao,qqq
110.xxx,vvv
[root@Ansible-server log]# sed -n '/101/ , /104/p' sed.txt
101,xiaoxu,ccc
102,xiaoli,bbb
103,xiaowang,ddd
104.xiaozhao,qqq
(6)、从某一行开始取几行
[root@moudle01 20:05:08 ~]# head -5 user
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@moudle01 20:06:26 ~]# sed -n "3,+1p" user
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@moudle01 20:06:38 ~]# sed -n "3,+2p" user
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
(7)、~
从某一行开始,按照某一步长去进行读取
[root@moudle01 20:10:03 ~]# cat abc
1
2
3
4
5
6
7
8
9
0
[[root@moudle01 20:09:51 ~]# sed -n "1~2p" abc
1
3
5
7
9
(8)、查找某一内容在第几行
# 输出除了第一行的内容
[root@moudle01 20:20:12 ~]# sed -n '1!p' user
# 输出最后一行
[root@moudle01 20:20:12 ~]# sed -n '$p' user
abc:x:1021:1021::/home/abc:/bin/bash
# 输出某一内容在第几行
[root@moudle01 20:16:22 ~]# sed -rn "/^apache/=" user
30
(6)、查找功能小结
- 核心掌握:
- 根据行号查找,模糊查找//,模糊表示范围(日志)
- 注意这里提到的行号,//方式到表示条件(找谁),除了给p(查找)用,还可以给修改,增加,删除使用
- 过滤时与grep类似支持正则表达式,sed -r支持扩展正则
- sed可以指定行号,sed表示过滤范围
5、sed修改(替换)
sed命令的替换格式说明
sed 's#找谁#提供换成什么#g' sed.txt
sed 's###g' sed.txt
推荐使用: ### @@@ ///
当查找替换的内容是# @ / 时就不要使用对应的符号作为分隔符了
s substitute 替换
g global 全局替换,这一行中把所有匹配到的内容都进行替换,如果不加g,则只替换每一行的第一个匹配到的内容
-i参数:直接修改文件内容,如果不加-i选项,并不会真正改变文件的内容。动作指令d、s和选项-i是在搭配一起使用的
修改文件内容之前先进行备份,然后再修改内容(一般用于替换一个文件) -i.bak
[root@Ansible-server log]# sed 's#[0-9]#ccc#g' sed.txt
ccccccccc,xiaoxu,ccc
ccccccccc,xiaoli,bbb
ccccccccc,xiaowang,ddd
ccccccccc.xiaozhao,qqq
ccccccccc.xxx,vvv
[root@Ansible-server log]# sed 's#[0-9]#ccc#' sed.txt
ccc01,xiaoxu,ccc
ccc02,xiaoli,bbb
ccc03,xiaowang,ddd
ccc04.xiaozhao,qqq
ccc10.xxx,vvv
[root@Ansible-server log]# sed -i.bak 's#xiaoxu#lili#g' sed.txt
[root@Ansible-server log]# ls sed.txt
sed.txt
[root@Ansible-server log]# ll sed.txt*
-rw-r--r--. 1 root root 74 May 5 19:59 sed.txt
-rw-r--r--. 1 root root 76 May 5 19:16 sed.txt.bak
# 把所有行的第二个符合条件数据替换
[root@moudle01 20:36:47 ~]# sed 's/2017/xxxx/2' sucai.txt
2017 2011 2035
2017 xxxx 4534
2017 xxxx 2017
# 把所有行的第三个符合条件数据替换
[root@moudle01 20:37:43 ~]# sed 's/2017/xxxx/3' sucai.txt
2017 2011 2035
2017 2017 4534
2017 2017 xxxx
# 只替换第二行的 第二个数据
[root@moudle01 20:37:48 ~]# sed '2s/2017/xxxx/2' sucai.txt
2017 2011 2035
2017 xxxx 4534
2017 2017 2017
# 在行号位置加正则
[root@moudle01 20:40:38 ~]# sed '/4534$/s/2017/xxxx/2' sucai.txt
2017 2011 2035
2017 xxxx 4534
2017 2017 2017
面试题
有一个文件,执行如下命令,会发生什么
sed 's9\98\9\99\978\99' filename
\:是转义字符
是以9作为分隔符
s9 \98\9\9 9 \987\9 9
将文件中的9899修改为9879
🔑s后面的第一个字符就是分隔符
- 小结
- 核心掌握sed命令替换的格式
- 核心掌握-i用法
6、sed替换进阶
(1)、后向引用格式
应用说明
后向引用或反向引用:适用于sed命令处理/提取某一行中的部分内容,sed命令配合正则实现取列(类似于awk命令)
是sed命令中用于处理列的方式
使用格式
使用替换形式:s###g
前2个井号之间通过正则与(),对数据进行分组,每一个()是一个组
后面两个井号之间通过\数字,去调用前面分组的内容
整体式后面调用前面分组的内容,称之为反向引用/后向引用
应用场景:某一行中对部分数据进行加工与处理,提取某一部分数据
[root@Ansible-server log]# echo 12345678 | sed -r 's#(1)(.*)(8)#\1<\2>\3#g'
1<234567>8
(2)、案例01
交换/etc/passwd下第一列和第二列的内容
[root@Ansible-server opt]# sed -r 's#(^.*)(:.*:)(.*$)#\3\2\1#g' passwd
/bin/bash:/root:root:x:0:0:root
(3)、案例02
提取IP
[root@Ansible-server opt]# ip address show ens160 | sed -n '4p' | sed -r 's#(^.* )(.*)(/.*$)#\2#g'
192.168.121.141
(4)、案例03
root@moudle01[09:32:33]:/script
$ cat abc.txt
100 laownag
89 xxx
666 w
root@moudle01[09:32:24]:/script
$ sed -r 's/([0-9]+)(\s+)(\w+)/\3\2\1/' abc.txt
laownag 100
xxx 89
wu 666
7、sed删除
- d:sed命令删除是按照行为单位进行
- 如果仅仅删除某一行的一个字符,使用替换
[root@Ansible-server opt]# sed '1,3d' /var/log/sed.txt
104.xiaozhao,qqq
110.xxx,vvv
-
案例
-
排除文件中的空行和带注释的行
[root@Ansible-server opt]# sed -r '/^$|#/d' /etc/ssh/sshd_config [root@Ansible-server opt]# egrep -v '^$|#' /etc/ssh/sshd_config [root@Ansible-server opt]# awk '!/^$|#/' /etc/ssh/sshd_config
# 除了bin开头的行,其他行全删除
[root@moudle01 20:26:29 ~]# sed '/^bin/!d' user
bin:x:1:1:bin:/bin:/sbin/nologin
# 删除文件最后一行
[root@moudle01 20:29:11 ~]# sed '$d' user
8、sed增加
- cai
- a:append,在指定行下面追加内容
- i:insert,在指定行上面加上内容
- c:replace,清空当前行,后续的内容作为当前行的内容
[root@Ansible-server opt]# cat sed.txt
101,lili,ccc
102,xiaoli,bbb
103,xiaowang,ddd
104.xiaozhao,qqq
110.xxx,vvv
[root@Ansible-server opt]# sed '3a hahaha' sed.txt
101,lili,ccc
102,xiaoli,bbb
103,xiaowang,ddd
hahaha
104.xiaozhao,qqq
110.xxx,vvv
[root@Ansible-server opt]# sed '3i hahaha' sed.txt
101,lili,ccc
102,xiaoli,bbb
hahaha
103,xiaowang,ddd
104.xiaozhao,qqq
110.xxx,vvv
[root@Ansible-server opt]# sed '3c hahaha' sed.txt
101,lili,ccc
102,xiaoli,bbb
hahaha
104.xiaozhao,qqq
110.xxx,vvv
本文来自博客园,作者:Linux小菜鸟,转载请注明原文链接:https://www.cnblogs.com/xuruizhao/p/18304815