1. 介绍

sed命令: 字符流编辑器。常见的行为单位的文件编辑器。

sed命令的作用: 擅长对行进行操作

对文件进行修改调整。

其实等同于vi的作用。只是它跟文件本身的交互不太多了。不需要在屏幕上打开文件。

语法格式

sed 参数 条件-处理 文件

准备个测试的数据文档

vi person.txt
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
2. 查看
  1. 将带有zhengzhou的行打印出来
sed -n '/zhengzhou/p' person.txt 
2,henan,zhengzhou
-n 抑制内存内数据的输出,只打印匹配的行。
p 放在最后 等同于print
// 代表匹配中间的内容
不加-n 则如下 匹配的行会打印两次
sed '/zhengzhou/p' person.txt
1,zhejiang,hangzhou
2,henan,zhengzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
  1. 打印从zhejiang到hebei的行。
sed -n  '/zhejiang/,/hebei/p' person.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai

但是 如果把测试文档改一下,改成这样

1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai

sed -n '/zhejiang/,/hebei/p' person.txt
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai

输出的结果依然是一样的。 这就涉及到了,sed的匹配机制。

sed 默认会从上往下开始匹配,当找到了第一个hebei的时候,它就会认为,任务已经完成了,就会返回相关的内容。

  1. 打印带有zhejiang和hebei的行。

和2不太一样,2是从..到..。 3 是和。

sed]# sed -n  '/zhejiang/p;/hebei/p' person.txt
1,zhejiang,hangzhou
3,hebei,xingtai
6,hebei,xingtai

sed命令的执行过程
条件-执行 条件-执行, 所以需要打两个P 。 分号作用约等于 |
  1. 打印第三行
sed]# sed -n '3p' person.txt 
3,hebei,xingtai
  1. 打印以3开头的行
sed]# sed -n '/^3/p' person.txt 
3,hebei,xingtai
  1. 打印文本的最后一行
sed]# sed -n '$p' person.txt 
6,hebei,xingtai
3. 添加
  1. 在第一行 插入 7,zhejiang,jinhua(或者说 把 7,zhejiang,jinhua 插入到第一行)
sed]# sed  '1i7,zhejiang,jinhua' person.txt 
7,zhejiang,jinhua
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai

1: 第一行
i insert i代表插入到某个位置
  1. 在第一行下面插入7,zhejiang,jinhua (等于插入到第二行)
[root@k8s-vip sed]# sed  '1a7,zhejiang,jinhua' person.txt 
1,zhejiang,hangzhou
7,zhejiang,jinhua
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai
[root@k8s-vip sed]# sed '2i7,zhejiang,jinhua' person.txt
1,zhejiang,hangzhou
7,zhejiang,jinhua
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai
  1. 匹配带有henan的行,在行前插入hebei,行下面插入shandong
sed]# sed -e '/henan/ihebei' -e '/henan/ashandong' person.txt 
1,zhejiang,hangzhou
hebei
2,henan,zhengzhou
shandong
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai

-e 单个语句内执行多个命令
  1. 在文件最下下面插入两行内容anyang xinxiang
[root@k8s-vip sed]# sed '$aanyang\nxinxinag' person.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai
anyang
xinxinag

$ 末尾
\n 换行符
该方法常用于编写配置文件
  1. 将匹配的行写入到一个新文件内
[root@k8s-vip sed]# ls
person.txt person.txt.bak test.txt
[root@k8s-vip sed]# sed -n '/zhejiang/w 123' person.txt
[root@k8s-vip sed]# ll
总用量 16
-rw-r--r-- 1 root root 20 11月 8 22:25 123
-rw-r--r-- 1 root root 110 11月 8 18:25 person.txt
-rw-r--r-- 1 root root 110 11月 8 18:24 person.txt.bak
-rw-r--r-- 1 root root 106 11月 6 23:47 test.txt
[root@k8s-vip sed]# cat 123
1,zhejiang,hangzhou

w 匹配的内容 写到一个新文件内
这里用-n是避免将整个文件都写进去
123 新文件的名字
4. 删除
  1. 删除文件中第3行的内容
[root@k8s-vip sed]# sed '3d' person.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai
[root@k8s-vip sed]# cat person.txt #对比。第三行消失了
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai

d delete 删除
  1. 删除第2行到第5行
[root@k8s-vip sed]# sed '2,5d' person.txt 
1,zhejiang,hangzhou
6,hebei,xingtai
用逗号表示 到
  1. 删除有hebei的行
[root@k8s-vip sed]# sed '/hebei/d' person.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
4,shandong,jinan
5,shanxi,xian
  1. 删除第2行和第6行
[root@k8s-vip sed]# sed  '2d;6d' person.txt 
1,zhejiang,hangzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
  1. 匹配zhejiang删除zhejiang的下一行
sed]# sed  '/zhejiang/{n;d}' person.txt
1,zhejiang,hangzhou
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.5
  1. 利用sed取消空行输出
取一个新的文本;
[root@k8s-vip sed]# cat test.txt
1,zhejiang,hangzhou

2,henan,zhengzhou

3,hebei,xingtai

4,shandong,jinan

5,shanxi,xian

6,hebei,xingtai

[root@k8s-vip sed]# sed '/^$/d' test.txt
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai

^$表示空行
[root@k8s-vip sed]# sed -n '/^$/!p' test.txt
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai
!p !取反
5. 替换
  1. 将文件中hebei 替换为 hb
[root@k8s-vip sed]# sed  's#hebei#hb#g' person.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hb,xingtai
4,shandong,jinan
5,shanxi,xian
6,hb,xingtai

s 代表替换
### 定界符。 也可以用 @@@ ///等来代替
g 代表匹配所有。不写则只替换每行匹配到的第一处
  1. 把10.0.0.5改为10.0.0.6
改下文本
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai
10.0.0.5

[root@k8s-vip sed]# sed -r 's#(.*)5#\16#g' person.txt
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.6
(.*) 用于匹配 10.0.0.
\1 表示引用上个括号的内容
-r 引用正则
  1. 把2开头的行,换为 123qwe
sed]# sed  '/^2/c 123qwe' person.txt
1,zhejiang,hangzhou
123qwe
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.5
c 代表整行替换
  1. 把第2到第4行进行注释
[root@k8s-vip sed]# sed '2,4s@^@#@g' person.txt
1,zhejiang,hangzhou
#2,henan,zhengzhou
#3,hebei,xingtai
#4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.5

sed]# sed '2,4s@^@#&@g' person.txt
1,zhejiang,hangzhou
#2,henan,zhengzhou
#3,hebei,xingtai
#4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.6
^ 匹配所有# 不知道为啥,反正能这么用
& 代表前面匹配到的内容。 配合 ^$可在匹配到的内容前后添加内容
6. 模式空间和暂存空间

模式空间:是sed软件从文本读取一行文本然后存入的缓冲区(这个缓冲区是在内存中的),然后使用sed命令操作模式空间的内容。

暂存空间:可以通过 h H 将模式空间的内容,放在暂存空间, 可以用 gG提取出来

h  模式空间的内容,重定向到暂存空间
H 模式空间的内容,追加到暂存空间
g 暂存空间的内容,复制到模式空间,会覆盖原因内容
G 暂存空间的内容,复制到模式空间,追加至原内容后面
  1. 将带有浙江的行,覆盖掉最后一行
sed]# sed '/zhejiang/h;$g' person.txt
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
1,zhejiang,hangzhou
  1. 将带有浙江的行,覆盖掉最后一行。并将其在文件中删除
sed]# sed '/zhejiang/{h;d};$g' person.txt
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
1,zhejiang,hangzhou
  1. 将带有浙江的行,追加到最后一行。并将其在文件中删除
sed]# sed '/zhejiang/{h;d};$G' person.txt
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.6
1,zhejiang,hangzhou
  1. 将带有浙江的行,追加到最后一行。并将其在文件中删除
sed]# sed '/zhejiang/{H;d};$G' person.txt
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.6

1,zhejiang,hangzhou

暂存空间中。默认有个空行的,所以一般用小h而不是大h
7. 补充
  1. 以上提到的都是在模式空间内进行的修改。并没有真的保存在文件里
  2. 使用 -i 参数,可以真实的保存在内存中。 但为了安全 一般用。i.bak 自动生成一个备份文件
  3. -i 参数一定要用到最后。例如 -ri
  4. 引号的区别
双引号:把双引号的内容输出出来;如果内容中有命令,变量等,会先把命令,变量解析出结果,然后再输出最终内容来。双引号内命令或变量的写法为`命令或变量`或$(命令或变量)
单引号:所见即所得,将单引号内的内容原样输出,阻止所有字符的转义
不加引号:不会将含有空格的字符串视为一个整体输出,如果内容中有命令,变量等,会先把命令,变量解析出结果,然后再输出最终内容来,如果字符串含有空格等特殊字符,则不能完整输出,则需改加双引号。
倒引号(反引号Esc键下方):进行命令的替换,在倒引号内部的shell命令将会被执行,其结果输出代替用倒引号括起来的文本。