1 sed编辑器
sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。
sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本文件中。
sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
2 sed的工作流程
sed的工作流程主要包括读取、执行和显示三个过程:
- 读取: sed从输入流 (文件、管道、标准输入) 中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space )。
- 执行: 默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则sed命令将会在所有的行上依次执行。
- 显示: 发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。在所有的文件内容都被处理完成之前,上述过程将重复执行, 直至所有内容被处理完。
在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。
注意:默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非使用"sed -i"修改源文件、或使用重定向输出到新的文件中。
3 sed命令格式
命令格式:
sed -e '操作' 文件1 文件2 sed -n -e '操作' 文件1 文件2 sed -f 脚本文件 文件1 文件2 sed -i -e '操作' 文件1 文件2 复制代码
执行多条命令的三种方法:
sed -n -e '操作1' -e '操作2' 文件 sed -n -e '操作1;操作2' 文件 sed -e 'n{ 操作1 操作2 ...... }' 文件1 复制代码
常用选项:
选项 | 作用 |
-e 或--expression= | 表示用指定命令来处理输入的文本文件,只有一个操作命令时可省略,一般在执行多个操作命令使用 |
-f 或--file= | 表示用指定的脚本文件来处理输入的文本文件 |
-h 或--help | 显示帮助 |
-n、--quiet或--silent | 禁止sed编辑器输出,但可以与p命令一起使用完成输出 |
-i | 直接修改目标文本文件 |
常用操作:
操作 | 作用 |
s | 替换,替换指定字符 |
d | 删除,删除选定的行 |
a | 增加,在当前行下方增加一行指定内容 |
i | 插入,在选定行上方插入一行指定内容 |
c | 替换,将选定行替换为指定内容 |
y | 字符转换,转换前后的字符长度必须相同 |
p | 打印行内容。如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以ASCII码输出。其通常与"-n"选项一起使用 |
= | 打印行号 |
l (小写L) | 打印数据流中的文本和不可打印的ASCII字符(比如结束符$、制表符\t) |
sed的核心功能:增删改查(可配合正则表达式)
查: p 删: d 改: s(字符串替换)、c(整行替换)、y(对应字符进行替换,效果类似tr命令) 增: i(在行前插入内容)、a(在行后添加内容)、r(在行后读入文件的内容) 复制粘贴:H(复制)、d(删除)、G(粘贴到指定行下方) 复制代码
4 sed 查找打印p
4.1 不指定行(顺序处理每一行)
1、sed编辑器默认输出行内容,-n选项可以禁止输出。如果不加-n,却使用p操作,那么每行内容会打印两次。
sed -e "p" :每行内容打印两次。
sed -n "p" :每行内容只打印一次。
[root@yuji ~]# cat ff.txt //查看文件内容,共10行 one two three four five six seven eight nine ten [root@yuji ~]# sed -e 'p' ff.txt //每行内容会打印两次 one one two two three three four four five five six six seven seven eight eight nine nine ten ten [root@yuji ~]# sed -n -e 'p' ff.txt //每行内容只打印一次 one two three four five six seven eight nine ten 复制代码
2、'n' 打印行号。
sed -n '=' :只打印行号。
sed -e 'n' : 打印行号和行内容。
sed -n '=;p' :打印行号和行内容。
[root@yuji ~]# sed -n '=' ff.txt //只打印行号 1 2 3 4 5 6 7 8 9 10 [root@yuji ~]# sed -e '=' ff.txt //打印行号和行内容 1 one 2 two 3 three 4 four 5 five 6 six 7 seven 8 eight 9 nine 10 ten 复制代码
3、sed 执行多条命令的三种方法。
以打印行号和行内容为例:
#方法一 sed -n -e '=' -e 'p' file.txt #方法二 sed -n -e '=;p' file.txt #方法三:换行操作 sed -n ' = p ' file.txt 复制代码
4、'l' 打印文本即隐藏字符(结束符$,制表符\t)。
[root@yuji ~]# sed -n 'l' ff.txt one$ two$ three$ four$ five$ six$ seven$ eight$ nine$ ten$ 复制代码
4.2 sed 对指定行进行操作
两种方法:
- 以数字形式表示行区间;
- 用文本模式(字符串)来过滤出行(一般结合正则表达式)。
以数字形式表示行区间:
操作 | 含义 |
'1p' | 打印第一行 |
'$p' | 打印最后一行 |
'1,3p' | 打印连续行,打印第一行到第三行 |
'6,$p' | 打印第六行到最后一行 |
'1,+3p' | 打印第一行加后面三行(即打印第一到第四行) |
'5q' | 打印前五行后退出 |
'p;n' | 打印奇数行 |
'n;p' | 打印偶数行 |
使用字符串匹配出行:
操作 | 含义 |
'/root/p' | 打印包含root的行 |
'/root/!p' | 打印不包含root的行。! 表示取反 |
'/^root/p' | 打印以root开头的行 |
'/bash$/' | 打印以bash结尾的行 |
'/root l bash/p' | 打印包含root或bash的行。"l"是扩展正则表达式的元字符,要使用sed -r |
'6,/root/p' | 打印第6行到第一个包含root的行 |
4.2.1 以数字形式表示行区间
1、打印单行。
[root@yuji ~]# sed -n '1p' ff.txt one [root@yuji ~]# sed -n '3p' ff.txt three [root@yuji ~]# sed -n '$p' ff.txt //打印最后一行 ten [root@yuji ~]# sed -n -e '1p' -e '5p' ff.txt //打印第一行、第五行 one five 复制代码
2、打印连续的行,使用逗号。
[root@yuji ~]# sed -n '1,3p' ff.txt one two three [root@yuji ~]# sed -n '6,$p' ff.txt six seven eight nine ten 复制代码
3、'1,+3p',打印第1行加后面3行(即打印第1~4行)。
[root@yuji ~]# sed -n '1,+3p' ff.txt one two three four 复制代码
4、打印第1~5行的三种方法:
[root@yuji ~]# sed -n '1,5p' ff.txt one two three four five [root@yuji ~]# sed -n '1,+4p' ff.txt one two three four five [root@yuji ~]# sed -e '5q' ff.txt one two three four five 复制代码
5、使用sed输出奇数行或者偶数行。
'n' :next,读取下一行。
'p' :打印当前所在行。
[root@yuji ~]# sed -n 'p;n' ff.txt one three five seven nine [root@yuji ~]# sed -n 'n;p' ff.txt two four six eight ten 复制代码
6、打印除了第一行以外的奇数行。
[root@yuji ~]# sed -n '2,${n;p}' ff.txt three five seven nine 复制代码
7、比较 'p;n;p' 和 'n;p;n' 。
[root@yuji ~]# sed -n 'p;n;p' ff.txt one two three four five six seven eight nine ten [root@yuji ~]# sed -n 'n;p;n' ff.txt two five eight 复制代码
小贴士:
'n' :next,读取下一行。 'p' :打印当前所在行。 # 'p;n' 处理过程: 自动读取第1行,p打印第1行,n读取第2行; 自动读取第3行,p打印第3行,n读取第4行; 自动读取第5行,p打印第5行,n读取第6行; ...... # 'n;p' 处理过程: 自动读取第1行,n读取第2行,p打印第2行; 自动读取第3行,n读取第4行,p打印第4行; 自动读取第5行,n读取第6行,p打印第6行; ...... # 'p;n;p' 处理过程: 自动读取第1行,p打印第1行,n读取第2行,p打印第2行; 自动读取第3行,p打印第3行,n读取第4行,p打印第4行; 自动读取第5行,p打印第5行,n读取第6行,p打印第6行; ...... # 'n;p;n' 处理过程: 自动读取第1行,n读取第2行,p打印第2行,n读取第3行; 自动读取第4行,n读取第5行,p打印第5行,n读取第6行; 自动读取第7行,n读取第8行,p打印第8行,n读取第9行; ...... 以此类推。 复制代码
4.2.3 使用正则表达式,匹配行内容
注意:sed 使用扩展正则表达式时,要加 -r 。
示例1:
先将/etc/passwd 文件复制到家目录下并改名为pass.txt,方便演示。
[root@yuji ~]# cp /etc/passwd pass.txt //复制文件并改名 [root@yuji ~]# sed -n '/root/p' pass.txt //打印包含root的行 root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@yuji ~]# sed -n '/^root/p' pass.txt //打印以root开头的行 root:x:0:0:root:/root:/bin/bash [root@yuji ~]# sed -n '/bash$/p' pass.txt //打印以bash结尾的行 root:x:0:0:root:/root:/bin/bash yuji2:x:1000:1000:yuji2:/home/yuji2:/bin/bash nancy:x:1021:1021::/home/nancy:/bin/bash helen:x:1022:1022::/home/helen:/bin/bash 复制代码
示例2:
[root@yuji ~]# sed -n '6,/root/p' pass.txt //从第6行开始打印,一直到第一个包含root的行 sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin [root@yuji ~]# sed -n '6,/root/=' pass.txt //从从第6行开始打印行号,一直到第一个包含root的行 6 7 8 9 10 复制代码
示例3:
sed -r 支持扩展正则表达式。同时在 使用{n}、{n,}、{n,m}时,括号{}前不需要加反斜杠\ 。
[root@yuji ~]# sed -n '/ro{2,}t/p' pass.txt root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@yuji ~]# sed -n -r '/ro{2,}t/p' pass.txt root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin #打印包含root或bash的行 [root@yuji ~]# sed -n '/root|bash/p' pass.txt //如果不加-r,则"|"前要加转义符\ root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin yuji2:x:1000:1000:yuji2:/home/yuji2:/bin/bash nancy:x:1021:1021::/home/nancy:/bin/bash helen:x:1022:1022::/home/helen:/bin/bash [root@yuji ~]# sed -n -r '/root|bash/p' pass.txt //"sed -r"支持扩展正则表达式 root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin yuji2:x:1000:1000:yuji2:/home/yuji2:/bin/bash nancy:x:1021:1021::/home/nancy:/bin/bash helen:x:1022:1022::/home/helen:/bin/bash 复制代码
5 sed 删除d
示例1:
以数字形式表示行区间。
[root@yuji ~]# cat ff.txt one two three four five six seven eight nine ten [root@yuji ~]# sed '3d' ff.txt //删除第3行 one two four five six seven eight nine ten [root@yuji ~]# sed '5,8d' ff.txt //删除第5~8行 one two three four nine ten [root@yuji ~]# sed '$d' ff.txt //删除最后一行 one two three four five six seven eight nine [root@yuji ~]# sed 'd' ff.txt //删除所有行 [root@yuji ~]# sed '1,+3d' ff.txt //删除第1行及后面3行(即删除第1~4行) five six seven eight nine ten [root@yuji ~]# sed '6,$d' ff.txt //删除第6行到最后一行 one two three four five [root@yuji ~]# sed '6!d' ff.txt //除了第6行,其他都删除 six [root@yuji ~]# sed '6,$!d' ff.txt //除了第6行到最后一行,其他都删除 six seven eight nine ten 复制代码