Loading... <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 16px;text-decoration: underline"><strong>前言</strong></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">我在参考其它多个Blog中发现,有些Blog中sed的功能介绍和实际有出入,这可能和版本有关系,正如sed文档中所说“might change in future versions”,所以本文sed是以4.2.1为例。如果以后sed更新版本了,有可能会不一样。</span><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><br /></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px"><em><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">好记性不如烂笔头!</span></em></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 16px;text-decoration: underline"><strong>sed的工作原理</strong></span><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><br /></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">sed维护着两个数据的缓冲空间,一个是模式空间(<em>pattern</em> space)和另外一个保留空间(<em>hold</em> space),在初始环境下都为空。</span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">sed是一个流编辑器,它会循环的从输入流中读取每一行,直到读完整个文件。具体如下:</span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">首先,它会从输入流中读取一行(如果刚开始就是第一行),移除行尾的换行符,放置于模式空间当中,接着一条条的运行命令(命令可以有多个并且是按序执行,如果某个命令地址定界了一个行号,只有满足该行号才会执行命令,<em>如“1d”,意思是如果是第一行则删除模式空间内的内容</em>)。</span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">当命令运行完毕之后,除非使用了 -n 选项,否则会把模式空间的内容加上之前删过的换行符并打印到输出。然后读入下行,执行下一个循环。如果没有使诸如‘D’的特殊命令,那会在两个循环之间清空模式空间,但不会清空<span style="font-family: 微软雅黑;font-size: 14px;text-decoration: none">保留</span>空间。</span><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><br /></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><em>意译自</em><em>http://www.gnu.org/software/sed/manual/sed.html中 3.1 How <samp>sed</samp> Works</em></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">流程图如下</span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><img title="1435746315207352.jpg" alt="sed 工作原理.jpg" src="//cto.wang/usr/uploads/2016/07/20160703160558-92.jpg" /></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">注:上面只是标准流程,某些特殊命令会有自己的流程</span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><br /></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 16px;text-decoration: underline"><strong>n N的说明</strong></span><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: underline"><strong><br /></strong></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">范例文件1</span></p> <pre class="brush:bash;toolbar:false">[root@CZ tmp]# cat 1 1 2 3 4 5 6 7 8 9 10 11</pre> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px"> </span><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><br /></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px"><strong><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">n:打印当前模式空间内容,然后读取下一行并替代当前模式空间的内容。<span style="font-family: 微软雅黑;font-size: 14px">如果读取不到下一行sed则会不运行之后的命令</span></span></strong></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">我们通过以下命令了解一下n<br /></span></p> <pre class="brush:bash;toolbar:false">[root@CZ tmp]# sed 'n;d' 1 1 3 5 7 9 11</pre> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">上面命令过程是这样</span></p> <ol class=" list-paddingleft-2"> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">先读取第一行进模式空间(以后简称为1)</span></p> </li> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">执行命令n,过程如下</span></p> </li> <ol class=" list-paddingleft-2"> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">打印1到输出</span></p> </li> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">读取2并覆盖到模式空间</span></p> </li> </ol> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">执行命令d,过程如下</span></p> </li> <ol class=" list-paddingleft-2"> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">删除模式空间的内容</span></p> </li> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">立即执行下一循环(d命令在运行后会直接执行下一循环,所以它并不会执行之后的命令和打印模式空间,具体d介绍会留在下次分享)</span></p> </li> </ol> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">按照上面的流程循环执行…….直到读取到11(最后一行),11的具体过程如下</span></p> </li> <ol class=" list-paddingleft-2"> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">读取11进模式空间</span></p> </li> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">运行命令n,不过读取不到下一行</span></p> </li> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">因为读不到,所以sed退出所有的命令,也就是说它不会执行命令d</span></p> </li> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">加回换行符并打印模式空间的内容到输出,当前模式空间内容为11,所以输出11</span></p> </li> </ol> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">已经是文件尾,sed结束运行。 </span></p> </li> </ol> <p> </p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px"><strong><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">N:读取下一行并且附加到当前模式空间内,<span style="font-family: 微软雅黑;font-size: 14px"><span style="font-family: 微软雅黑;font-size: 14px"><strong>如果读取不到下一行sed则会不运行之后的命令</strong></span></span></span></strong></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">我们通过以下命令了解一下N</span></p> <pre class="brush:bash;toolbar:false">[root@CZ tmp]# sed 'N;a---' 1 1 2 --- 3 4 --- 5 6 --- 7 8 --- 9 10 --- 11</pre> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">上面命令过程是这样</span></span></p> <ol class=" list-paddingleft-2"> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">读取1进模式空间</span></p> </li> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">执行命令N</span></p> </li> <ol class=" list-paddingleft-2"> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">读取2并附加到模式空间,<span style="font-family: 微软雅黑;font-size: 14px;text-decoration: none">当前模式空间内容</span>为“1\n2”</span></p> </li> </ol> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">执行命令a—</span></p> </li> <ol class=" list-paddingleft-2"> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">在模式空间后附加一行‘—’当前模式空间内容为“1\n2\n—"</span></p> </li> </ol> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">打印模式空间内容</span></p> </li> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">循环执行直到读取11进模式空间,11的具体过程如下</span></p> </li> <ol class=" list-paddingleft-2"> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">读取11进模式空间</span></p> </li> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">执行命令N,不过读取不到下一行</span></p> </li> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">因为读不到,所以sed退出所有的命令,也就是说它不会执行命令a</span></span></p> </li> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px"><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px"><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">加回换行符并</span>打印模式空间的内容到输出,当前模式空间内容为11,所以输出11</span></span></span></p> </li> </ol> <li> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px"><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px">已经是文件尾,sed结束运行。 </span></span></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px"><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px"></span></span></span></p> </li> </ol> <p><span style="text-decoration: underline"><strong><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: underline">尾言</span></strong></span><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">:</span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">n N经常和d D一起用,不过D有点复杂,所以留在下次分享,不过我先剧透一下,D会删除模式空间内第一行,并且如果模式空间内容不为空,它会循环执行前面命令。直到为空才会执行下一循环。</span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px"><br /></span></span></p> <p><span style="text-decoration: underline"><strong><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: underline">参考</span></strong></span></p> <p><span style="text-decoration: underline"><strong><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: underline">http://www.gnu.org/software/sed/manual/sed.html</span></strong></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none">上面是官方文档,如果下面和上面冲突,请以上面为准,下面blog有些内容和我理解有出入,请自行判断。</span><span style="text-decoration: underline"><strong><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: underline"><br /></span></strong></span></p> <p>http://www.cnblogs.com/fhefh/archive/2011/11/14/2248942.html</p> <p>http://www.cnblogs.com/theCambrian/p/3606214.html <br />http://blog.csdn.net/yanquan345/article/details/19613443</p> <p>http://www.cnblogs.com/fhefh/archive/2011/11/22/2259097.html</p> <p></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px;text-decoration: none"><br /></span></p> <p><span style="font-family: 微软雅黑,Microsoft YaHei;font-size: 14px"> </span></p> 最后修改:2021 年 12 月 10 日 10 : 53 AM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 赞赏作者 支付宝微信