Sed进阶用法
文章目录
一、sed命令介绍
sed 是 stream editor 的缩写,中文称之为“流编辑器”。
sed 命令是一个面向行处理的工具,它以“行”为处理单位,针对每一行进行处理,处理后的结果会输出到标准输出(STDOUT)。你会发现 sed 命令是很懂礼貌的一个命令,它不会对读取的文件做任何贸然的修改(除非加上-i选项),而是将内容都输出到标准输出中。
- sed命令的语法:sed command file- command 部分:针对每行的内容所要进行的处理(这部分很重要很重要)。- file 部分:要处理的文件,如果忽略 file 参数,则 sed 会把标准输入作为处理对象。
- sed命令的选项与参数:
-n : 使用静默模式,在一般的sed的用法中,所有来自stdin(标准输出)的数据一般都会被列出到屏幕上。
但如果加上-n参数后,则只要经过sed特殊处理的那行才会被列出来。
-e : 直接在命令行模式上进行sed的操作编辑
-f : 直接将sed的操作写在一个文件内,-f filename则可以执行filename内的sed操作
-r : 使用扩展正则表达式的语法
-i : 直接修改文件内容,而不是输出到屏幕上
command说明:[n1][,n2] action
n1,n2 : 一般代表【选择进行操作(action)的行数】,举例:如果我的操作是需要在
5行到20行之间进行的,则【5,20[action]】。
action的参数:
单行模式空间
a : 新增。a的后面接字符,而这些字符会在新增到下一行
i : 插入。i的后面接字符,而这些字符会在新增到上一行
c : 替换。c的后面接字符,这些字符替换n1到n2的行
d : 删除。因为是删除,所以d后面通常不接任何东西
p : 打印。将匹配的数据打印出来。通常p会与选项-n一起使用
s : 替换。将文件原内容替换为新内容。举例:s/lod/new/g
n : 读取匹配的数据的下一行,覆盖模型空间的前一行(也就是被匹配的行),结果交给下一个参数处理
多行模式空间
N : 读取匹配的数据的下一行追加到模式空间,同时将两行看做一行,但是两行之间依然含有\n换行符
P : 打印。打印模式空间开端至\n(换行)之间的内容,并追加到默认输出之前。
D : 如果模式空间包含换行符,则删除模式空间开端至\n(换行)之间的内容, 并不会读取新的输入行,
而使用合成的模式空间重新启动循环。如果模式空间不包含换行符,则会像发出d命令那样启动正常的新循环
替换标记
g 表示行内全面替换。
p 表示打印行。
w 表示把行写入一个文件。
x 表示互换模板块中的文本和缓冲区中的文本。
y 表示把一个字符翻译为另外的字符(但是不用于正则表达式)
\\1 子串匹配标记
& 已匹配字符串标记
其它
! 表示后面的命令对所有没有被选定的行发生作用。
= 打印当前行号码。
# 把注释扩展到下一个换行符以前。
二、sed 的工作原理与流程
工作原理:
sed 命令是面向“行”进行处理的,每一次处理一行内容。处理时,sed 会把要处理的行存储在缓冲区中,接着用 sed 命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。这个缓冲区被称为“模式空间”(pattern space)。在这个处理过程中,sed 命令并不会对文件本身进行任何更改。
工作流程:
主要包括读取、执行和显示三个过程。
- 读取:sed 从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)。
- 执行:默认情况下,所有的 sed 命令都在模式空间中顺序地执行,除非指定了行的地址,否则 sed 命令将会在所有的行上依次执行。
- 显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。
2.1 模式空间与保持空间
模式空间(pattern space):sed处理文本内容行的一个临时缓冲区,模式空间中的内容会主动打印到标准输出,并自动清空模式空间
保持空间(hold space):sed处理文本内容行的另一个临时缓冲区,不同的是保持空间内容不会主动清空,也不会主动打印到标准输出,而是需要sed命令来进行处理
模式空间与保持空间的关系:
模式空间:相当于流水线,文本行在模式空间中进行处理;
保持空间:相当于仓库,在模式空间对数据进行处理时,可以把数据临时存储到保持空间;作为模式空间的一个辅助临时缓冲区,但又是相互独立,可以进行交互,命令可以寻址模式空间但是不能寻址保持空间。可以使用高级命令h,H,g,G与模式空间进行交互。
模式空间与保持空间进行交互:
d : 删除模式空间的内容,开始下一个循环
D : 删除模式空间/n(换行符)前面的内容
h : 【复制】模式空间的内容至保持空间(会覆盖保持空间的原内容)
H : 把模式空间的内容【追加】至保持空间
g : 【复制】保持空间的内容至模式空间(会覆盖模式空间的原内容)
G : 把保持空间的内容【追加】至模式空间
x : 【交换】模式空间与保持空间的内容
三、sed命令演示
注意!以下的演示都未加
-i
,所以对实际文件内容不产生任何效果。
#使用sed命令对该文件进行演示[root@localhost ~]# cat passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
=======================================#用a参数在第一行的下面插入test[root@localhost ~]# sed '1atest' passwd
root:x:0:0:root:/root:/bin/bash
test
bin:x:1:1:bin:/bin:/sbin/nologin
#用i参数在第二行的上面插入hello[root@localhost ~]# sed '2ihello' passwd
root:x:0:0:root:/root:/bin/bash
hello
bin:x:1:1:bin:/bin:/sbin/nologin
#用c参数把第二行替换为hello[root@localhost ~]# sed '2chello' passwd
root:x:0:0:root:/root:/bin/bash
hello
#用d参数删除匹配到‘root’的行[root@localhost ~]# sed '/root/d' passwd
bin:x:1:1:bin:/bin:/sbin/nologin
#单独用s参数替换文件内容只会替换该行匹配到的第一个[root@localhost ~]# sed 's/root/tom/' passwd
tom:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
#s和g搭配使用可达到替换全部匹配到的效果[root@localhost ~]# sed 's/root/tom/g' passwd
tom:x:0:0:tom:/tom:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
#单独使用p参数可以看到不仅打印出匹配‘root’的行,还把原本内容 \#一起显示出来了,这是因为sed的特性,文章开头的一段话就说明了。[root@localhost ~]# sed '/root/p' passwd
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
#通常p参数会搭配-n选项一起使用,-n是静默模式[root@localhost ~]# sed -n '/root/p' passwd
root:x:0:0:root:/root:/bin/bash
#使用y参数进行大小写转换[root@localhost ~]# sed 'y/abdef/ABDEF/' test
A FriEnD is somEonE
with whom you
DArE to BE yoursElF.
[root@localhost ~]# sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' test
A FRIEND IS SOMEONE
WITH WHOM YOU
DARE TO BE YOURSELF.
#用n参数读取当前行(匹配到的行)的下一行至模式空间,n参数会覆盖模式空间的 \#前一行(也就是含有'root'的行)。此时模式空间只有‘下一行’,后面的d参数会 \#删除模式空间的内容,所以sed会打印出含有root的行[root@localhost ~]# sed '/root/n;d' passwd
root:x:0:0:root:/root:/bin/bash
#在前面看到的都是单行模式。每次sed处理一个行。#但是sed是允许一次处理多行的。加上N参数追加进模式空间,此时\#sed将两行看做一行,这就是所谓的多行模式空间。#以下几行是用于sed对多行模式空间进行操作练习的文件内容[root@localhost ~]# cat test
A friend is someone
with whom you
dare to be yourself.
#可以发现使用N参数没有内容被打印出来,是因为N参数读取当前行的下一行至模式空间时\#并不会覆盖模式空间的上一行,此时模式空间‘当前行’与‘下一行’都存在,后面的d参数会\#模式空间的内容,所有没有内容被打印出来[root@localhost ~]# sed '/root/N;d' passwd[root@localhost ~]##使用N参数追加匹配到的行至模式空间,然后使用s参数进行替换,由于使用N参数,原本\#内容的两行此时在模式空间里被当作一行进行处理,把\n替换为空格后,由于中间没有了\#换行符,打印到屏幕上时会显示为一行[root@localhost ~]# sed '/A/{N;s/someone\n/someone /}' test
A friend is someone with whom you
dare to be yourself.
#对上条命令做了一点小小的修改。先说说这条命令要达成什么效果吧“把第二行的with挪到第一行”\#这里的思路其实就是把换行符变动了位置,达到了把第二行的开头挪到第一行的结尾的效果[root@localhost ~]# sed '/A/{N;s/someone\nwith /someone with\n/}' test
A friend is someone with
whom you
dare to be yourself.
#咦?这里原本的第二行怎么不见了呢!来分析一下。首先把匹配的行读入模式空间,后面的N参数\#又把下一行追加至模式空间,此时模式空间有两行内容,但被看作一行,但这一行中间有\n,\#P参数只打印模式空间开头到\n之间的内容,也就是说\n之后的内容不会被打印出来[root@localhost ~]# sed -n '/A/N;P' test
A friend is someone
dare to be yourself.
#D参数使用下面的文本作讲解[root@localhost ~]# cat sed_D
This is 1
This is 2
This is 3
This is 4
This is 5#读取1,执行N,得出1\n2,执行D,得出2#执行N,得出2\n3,执行D,得出3#依此类推,得出5,执行N,条件失败退出,因无-n参数,故输出5[root@localhost ~]# sed 'N;D' sed_D
This is 5#模式空间与保持的交互#以下几行用作下面练习的文件内容[root@localhost ~]# cat test
A friend is someone
with whom you
dare to be yourself.
#先匹配含有w的行,N参数把下一行也追加至模式空间,此时有模式有两行内容\#h参数把模式空间的内容复制到保持空间,之后d参数删除模式空间的内容\[root@localhost ~]# sed '/w/{N;h;d}' test
A friend is someone
#[root@localhost ~]# sed '/w/{N;h;d};/A/{N;s#is#the#g;G}' test
A friend the someone
with whom you
dare to be yourself.
版权归原作者 夜风轻快 所有, 如有侵权,请联系我们删除。