sed学习笔记


sed是什么:

sed是一个非交互式的流编辑器(stream editor)。所谓非交互式,是指使用sed只能在命令行下输入编辑命令来编辑文本,然后在屏幕上查看输出;而所谓流编辑器,是指sed每次只从文件(或输入)读入一行,然后对该行进行指定的处理,并将结果输出到屏幕(除非取消了屏幕输出又没有显式地使用打印命令),接着读入下一行。整个文件像流水一样被逐行处理然后逐行输出。(via Walk in Mindfields  )

sed工作机制:

sed维护两个缓冲区,pattern space和hold space,命令开始执行之前都为空。

pattern space缓冲区用于临时保存每次读取的一行的内容,大部分的匹配和替换等等操作都是针对pattern space中的内容进行的,因此不会对输入文件有任何影响,而hold space则作为后备缓冲区使用,除非指定了一些特殊的命令(例如D删除命令),否则pattern space中的内容会在处理完一行之后清空,但hold space中的内容在处理完每一行时不会被删除。

也就是说pattern space相当于我们的内存,hold space相当于硬盘.处理的时候在内存里,处理过的就放回硬盘.(这是我的理解,有一点点不恰当,但是因此一些概念会比较好理解.)

具体来说,可以大致分为以下几步:

1.首先,从标准输入流读取一行,移除换行符,然后存入pattern space中

2.执行指定的命令,(每个命令都有一个可选的地址(可以是行号,也可能是一个正则表达式匹配),这个地址作为一个执行命令前的测试,指定了需要对那些行进行操作。当前行只有匹配的情况下才会执行命令。)

3.当指定所有的命令都执行完了之后,pattern space内容就被处理过了,sed默认会将pattern space中的内容打印到标准输出中,移除的换行符也会打印出来。本行操作完成。

4.然后sed会读取下一行的内容,再次执行相同的操作。直到行尾。

形式上,使用sed采用如下命令格式:

sed [options] 'SELECTION edit-instructions'  file(s) 

常用options:

-n :使用安静(silent)模式。在一般sed的用法中,所有来自STDIN的数据一般都会被列出到终端上。但如果加上-n参数后,则只有经过sed特殊处理的那一行(或者动作)才会被列出来。

-e :直接在命令列模式上进行sed的动作编辑;

-f :直接将sed的动作写在一个文件内,-f filename 则可以运行filename内的sed动作;

-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)

-i :直接修改读取的文件内容,而不是输出到终端。

 

1)范围选取

SELECTION 可以如下表达:

  • 单个行号:如1为取第一行,5为取第五行,$为取最后一行             
  • 行范围:如5,$ 为取从第五行到最后一行之间的文本行
  • 单个正则匹配:如/string/ 为取包含string的行
  • 一个正则匹配范围:如/^on/,/off$/ 为取从on开头的行到off结尾的行之间(含这两个匹配行)所包含的文本行。
  • 行范围与正则匹配范围集合:如10,/man/表示从第10行到包含有man的行之间的文本
  • 除去所匹配行外的范围:如/Llew/! 表示除了匹配Llew的行外其余的文本行     

2)打印命令

基本语法:SELSECTIONp 打印pattern space中的内容 

Task1:打印包含Franklin的行

sed -n '/Franklin/p' phonelist 

注意,选项-n 表示所有都不打印,而仅仅打印出匹配的行,可以试一试没有这个选项的情况。回顾sed机制,它会将文本一行行放在pattern space,不管你做什么样的后续操作、甚至不做任何编辑动作,它都会在command执行完后把pattern space打出来,这你就理解了为什么要用这个选项。

3)处理命令

a)  增改操作:

基本语法:

SELECTIONx\ 
text

其中斜杠后有回车,而x则为:

i 表示插入选中行前

a 表示追加在选中行之后

c 表示将选中行修改为text

Task2:在第二行前插入一个联系人Jonney, Wang 923-3322 

sed '2i\ 

Jonney, Wang 923-3322' phonelist  

Task3:在Martin, Marty所在行之后加入联系人Jonney, Wang 923-3322

sed '/Martin, Marty/a\  

Jonney, Wang 923-3322' phonelist 

Task4:将名字为Llewellyn的行记录都记为“BANNED”

sed '/Llewellyn/c\

BANNED' phonelist 

b)删除操作

基本语法:

SELECTIONd ,清除pattern space中的所有内容

Task5 删除最后一行:

sed '$d' phonelist

c)替换操作:

基本语法:

'SELECTION s/old string/new string/’ 替换所选区域中第一次出现的old string

'SELECTION s/old string/new string/g’ 替换所选区域中所有的old string

'SELECTION y/string1/string2/’ 对所选区域中的string1所含字符对应替换为string2中同位置的字符,与tr命令相同。

Task6:将第一个Robin替换为Robbins

sed 's/Robin/Robbins/' phonelist 

Task7:将所有Rob替换为John 

sed 's/Rob/John/g' phonelist

Task8:将/usr/bin/中的/bin/替换为/bin 

sed 's/\/bin\//\/bin/' paths 

在这种出现很多/的文件时需要\来进行转义,稍微一多就容易出错,那么采用如下的方式把替换分隔符的方式进行就好,其中感叹号只是一个其他类字符,换做另外一个字符(例如@)也是没有关系的: 

sed 's!/bin/!/bin!' paths 

Task9:加密所有的1234,规则为将文件中1、2、3、4对应改为A、B、C、D: 

sed 'y/1234/ABCD/' phonelist

d)写文件操作:

基本语法:'SELECTION command/w filename’

Task9:将所有Rob 改为Robbin,并将结果写到一个叫做result 的文件中

sed 's/Rob/Robbin/gw result' phonelist

e)读文件操作:

基本语法:'SELECTION command/r filename’

Task10:如果phonelist中存在Patterson,则将文件paths的内容加入到Patterson后的那一行

sed '/Patterson/r paths' phonelist 

f)批处理操作:

如果要处理的很多,我们也可以将sed命令写入一个脚本,然后运行时采用-f选项指定运行该脚本就行。请注意sed会将第一条命令执行的结果发给第二条执行,因此命令的顺序尤为重要。

基本语法:sed -f scriptfile  filename

另一种方式是使用-e选项,基本语法为:

-e ‘command1’ –e ‘command2’

Task11:将Martin替换Mary,将Tearrey替换为Tearrey 

sed -e 's/Martin/Mary/' -e 's/Terrell/Tearrey/' phonelist

另外一种方法,有点类似于C语言中分号的使用: 

sed 's/Martin/Mary/;s/Terrell/Tearrey/' phonelist

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM