目录
一.sed是什么
sed(Stream EDitor)是一个强大而简单的文本解析转换工具,可以读取文本,并根据指定的条件对文本内容进行编辑(删除、替换、添加、移动等),最后输出所有行或者仅输出处理的某些行。sed也可以在无交互的情况下实现相当复杂的文本处理操作,被广泛应用于Shell脚本中,用以完成各种自动化处理任务。
- sed 的工作流程主要包括读取、执行和显示三个过程。
- 读取:sed 从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)。
- 执行:默认情况下,所有的 sed 命令都在模式空间中顺序地执行,除非指定了行的地址,否则 sed 命令将会在所有的行上依次执行。
- 显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清
二.sed的原理
前提:首先对于一个文本文件来说,它是由至上而下的一行或N行组成。
- 1、当用sed命令对文本进行处理的时候,sed先读取对象的文本文件的第一行到模式空间中。
- 2、当有内容进入“模式空间”时,sed的编辑命令对模式空间中的内容进行编辑操作(修改,替换,删除,追加,显示等等)
- 3、模式空间中的内容编辑处理完成之后,sed把此内容通过标准输出(默认为显示器)打印出来,并删除模式空间中的内容。
- 4、第一行处理结束。从新读取第二行的内容进行处理,直到最后一行。
三.sed常用操作选项
sed命令:
命令 | 功能 |
a\ | 在当前行后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行 |
c\ | 用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用"\"续行 |
i\ | 在当前行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行 |
d | 删除行 |
h | 把模式空间里的内容复制到暂存缓冲区 |
H | 把模式空间里的内容追加到暂存缓冲区 |
g | 把暂存缓冲区里的内容复制到模式空间,覆盖原有的内容 |
G | 把暂存缓冲区的内容追加到模式空间里,追加在原有内容的后面 |
l | 列出非打印字符 |
p | 打印行 |
n | 读入下一输入行,并从下一条命令而不是第一条命令开始对其的处理 |
q | 结束或退出sed |
r | 从文件中读取输入行 |
! | 对所选行以外的所有行应用命令 |
s | 用一个字符串替换另一个 |
g | 在行内进行全局替换 |
w | 将所选的行写入文件 |
x | 交换暂存缓冲区与模式空间的内容 |
y | 将字符替换为另一字符(不能对正则表达式使用y命令) |
sed选项:
选项 | 功能 |
-e | 进行多项编辑,即对输入行应用多条sed命令时使用 |
-n | 取消默认的输出 |
-f | 指定sed脚本的文件名 |
退出状态
sed不向grep一样,不管是否找到指定的模式,它的退出状态都是0。只有当命令存在语法错误时,sed的退出状态才不是0。
正则表达式元字符:
与grep一样,sed也支持特殊元字符,来进行模式查找、替换。不同的是,sed使用的正则表达式是括在斜杠线"/"之间的模式。
如果要把正则表达式分隔符"/"改为另一个字符,比如o,只要在这个字符前加一个反斜线,在字符后跟上正则表达式,再跟上这个字符即可。例如:sed -n '\o^Myop' datafile
元字符 | 功能 | 示例 |
^ | 行首定位符 | /^my/ 匹配所有以my开头的行 |
$ | 行尾定位符 | /my$/ 匹配所有以my结尾的行 |
. | 匹配除换行符以外的单个字符 | /m..y/ 匹配包含字母m,后跟两个任意字符,再跟字母y的行 |
* | 匹配零个或多个前导字符 | /my*/ 匹配包含字母m,后跟零个或多个y字母的行 |
[] | 匹配指定字符组内的任一字符 | /[Mm]y/ 匹配包含My或my的行 |
[^] | 匹配不在指定字符组内的任一字符 | /[^Mm]y/ 匹配包含y,但y之前的那个字符不是M或m的行 |
.... | 保存已匹配的字符 | 1,20s/youyouself/\1r/ 标记元字符之间的模式,并将其保存为标签1,之后可以使用\1来引用它。最多可以定义9个标签,从左边开始编号,最左边的是第一个。此例中,对第1到第20行进行处理,you被保存为标签1,如果发现youself,则替换为your。 |
& | 保存查找串以便在替换串中引用 | s/my/**&**/ 符号&代表查找串。my将被替换为**my** |
\< | 词首定位符 | /\<my/ 匹配包含以my开头的单词的行 |
\> | 词尾定位符 | /my\>/ 匹配包含以my结尾的单词的行 |
x\{m\} | 连续m个x | /9\{5\}/ 匹配包含连续5个9的行 |
x\{m,\} | 至少m个x | /9\{5,\}/ 匹配包含至少连续5个9的行 |
x\{m,n\} | 至少m个,但不超过n个x | /9\{5,7\}/ 匹配包含连续5到7个9的行 |
四.sed的用法
1.sed的使用方法,调用sed 命令的语法有两种:
一.在命令行指定sed指令对文本进行处理:sed +选项 ‘指令’ 文件
二.先将sed指令保存到文件中,将该文件作为参数进行调用:sed +选项 -f 包含sed指令的文件 文件
五.用法示例
1.打印输出
sed 'p' wjh.txt #将文本再次打印一遍
sed -n 'p' wjh.txt #取消了默认打印功能
如何显示范围,行号:
打印出1-8行的内容,并显示行号
打印出第一行后续的八行的内容,并显示行号
打印出第一行,第三行,第五行的内容,并显示行号
#奇偶表示
打印出从第一行开始每隔两行的内容,并显示行数
打印出从第二行开始每隔两行的内容,并显示行数
打印出从第二行开始每隔三行的内容,并显示行数
打印出最后一行 :$
打印出行内带 'the' 的行数
打印出以 'bash' 结尾的字符的行数
打印出开头是w中间匹配包含任意一个字符,结尾是h的行数(两个字符之间差任意单字符就是差任意字符)
打印出包含任意数字的行数(因本文档每行开头标有数字排序所以全部打印出来了)
打印出开头为root的行数(root可以换成任意字符)
打印出除第一行以外所有行数 (!p为不打印,!的意思为取反)
打印除了nologin的其他所有行 (login可以换成任意字符)
打印出有root的每一行的行号
打印出有root的每一行的行号并且打印出行内容
打印出文件有多少行
打印文件行数是否校准
sed命令如果含有正则表达式命令则需要添加选项 'r'才能运行
可结合管道符进行
2.增加内容
a\ | 在当前行后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行 |
i\ | 在当前行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行 |
在第三行中插入操作(i:插入操作)
在第三行中插入操作,并将后续操作内容进行换行 (\:换行;在斜杠后面跟选项'n',不然无法显示换行效果)
在第一行下面增加内容 (a:增加内容),若要插入多行则(X,Ya)该语法表示x行到y行之间所有行下进行插入,(x;y;za)意思为在x,y,z下分别插入内容;
在有关键字得所有行下插入内容
注:a后面或者i后面得所有内容均可能会被认为是需要添加得内容
3.删除
d | 删除行 |
删除某行或者多行:
追加内容至文件行尾
4.替换
- g:行内全局替换
- p:显示替换成功的行
- w:将替换成功的行保存至文件中
- i:忽略大小写
在使用 sed 命令进行替换操作时需要用到 s(字符串替换)、c(整行/整块替换)、y
(字符转换)
例如:将root的字符串替换成wjh
这里没有真的改变文件内容,只是输出到屏幕,如果想要真的替换,需要用-i选项,建议用-i之前对原文件进行备份
5.搜索替换
使用 sed 命令进行替换操作时需要用到 s(字符串替换)、c(整行/整块替换)、y
(字符转换)命令选项
搜索root所在行,并且全部换成ROOT且打印出来
搜索字母o,仅替换每行第二个o为大写O
把1-5行的开头都插入#号把所有/sbin/nologin换成kgc,/需要转义但是使用默认的转义符之后阅读体验非常差,而且还容易写错,我们可以指定更有辨识度的转义符,例 如@,#,数字都可以,将原来的/替换成我们想要的
sed -n 's@/sbin/nologin@kgc@gp jay
sed -n 's/network/ooooo/igp' jay
将network替换成oooo并且不分大小写
6.插入文件
将/etc/hosts文件插入到第三行后面
sed '/2/r /etc/hosts' /tmp/passwd 把文件插入含有2的行后面
7.另存到文件
使用w指令将当前编辑的文件内容另存到其他文件中,如果目标文件已存在,则会将目标文件的内容覆盖
8.同时编辑
sed支持一个或多个-e参数9.分组操作
当我们需要对一行数据进行多次操作的时候我们可以使用{}进行分组
###分组 s//代表查找替换 ()代表分组 \1 代表留下的组 r:读取指定文件; [root@localhost ~]# echo 123abcxyz |sed -r 's/(123)(abc)(xyz)/\1/' #####从 ifconfig 命令的输出中提取 ens33 网卡的 IP 地址。通过 sed 的正则表达式匹配,它会找到 包含 inet 字段的行,并从中提取出 IP 地址部分,然后输出这个 IP 地址 [root@localhost ~]# ifconfig ens33|sed -rn '2s/.*inet ([0-9.]+) .*/\1/p
10.读取完退出
正常情况下sed会在读取完所有数据行之后退出,但是我们可以随时使用q指令来提前退出sed