sed工作原理
sed中文名叫流编辑器,大致意思是流动的方式编辑文本,即不需要人为手动打开文本进行编辑,通过sed自身的一些相应规则对文件进行匹配编辑,原理如下:
- sed编辑器逐行处理,并且将结果发送到屏幕。
- sed把当前正在处理的行保存在一个临时缓存区,这个缓存区称为模式空间或者临时缓存。
- sed还有一个空间,叫暂存缓存区或者保持空间;暂存缓存区辅助临时缓存区做文本处理。
- sed处理完模式空间的行后就把该行从模式空间中删除,然后进行读取下一行至模式空间。
- sed处理完模式空间的行后就把内容输出至屏幕,并且退出sed程序。
- 模式空间:可以想成工程里面的流水线,数据之间在它上面进行处理。
- 保持空间:可以想象成仓库,我们在进行数据处理的时候,作为数据的暂存区域。
sed与正则表达式
sed在查找文件内容时也需要正则表达式,默认使用正则表达式(RE),正则表达式是括在斜杠之间的模式,用于查找和替换。
示例
sh-4.2# sed -n '/RE/p' filename
如果要把正则表达式分隔符(/)改成其他字符,比如c,只要在这个字符前加一个反斜杠,在该字符后加入正则表达式,最后再跟上该字符即可;示例如下:
sh-4.2# sed -n '/love/p' filename
# 改成如下内容:
sh-4.2# sed -n 'clovecp' filename
这里的love就是正则表达式。
名词说明一下:/(斜杠),(反斜杠)
sed -n '/12/10/04/p' filename sed -n 'x12/10/04xp' filename # 说明: # 如果斜杠本身是正则表达式的一部分,必须在它前面加上反斜杠,以免和用作分隔符的斜杠混淆。 # x顶替斜杠成为分隔符,便于在正则表达式中包含斜杠。
sed定址
- sed定址用于决定对哪些行进行编辑;定址的形式可以有数字、正则表达式或者二者的结合。如果没有定址,sed默认处理所有行。
- 如果sed定址用的是数字,则这个数字表示行号。美元符号可以用来指输入文件的最后一行。如果给出的是逗号分隔的两个行号,那么需要处理的地址就是这两行之间的范围。范围可以是数字、正则表达式及两者的结合。
- sed可以根据定址进行打印、删除、修改等操作。
格式:sed 'command' filename
范例
1、 sed '1,3d' myfile
2、 sed -n '/[Jj]ohn/p' datafile
说明
1、 删除文件第1至第三行的内容
2、 只打印文件中包含John或者john关键字的行
sed命令与选项
sed范例
本文中的范例使用文件datafile作为输入文件。内容如下:
sh-4.2# cat datafile northwest NW Charles Main 3.0 .98 3 3 western WE Sharon Gray 5.3 .97 5 23 southwest SW Lewis Dalsass 2.7 .8 2 18 southern SO Suan Chin 5.1 .95 4 15 southeast SE Patricia Hemenway 4.0 .7 4 17 eastern EA TB Savage 4.4 .84 5 20 northeast NE AM Main Jr. 5.1 .94 3 13 north NO Margot Weber 4.5 .89 5 9 central CT Ann Stephens 5.7 .94 5 13
范例1
打印匹配关键字'north'的行,并且静默输出(取消默认的打印操作)
sh-4.2# sed -n '/north/p' datafile
范例2
删除第三行内容
sh-4.2# sed '3d' datafile
范例3
删除第三行内容至最后一行
sh-4.2# sed '3,$d' datafile
范例4
所有包含模式'north'的行都被删除;其余的行被打印
sh-4.2# sed '/north/d' datafile
范例5
将文件中所有west的关键字更换成north
sh-4.2# sed 's/west/north/g' datafile
范例6
将文件中所有west的开头的关键字更换成north,并且只打印该行
sh-4.2# sed -n 's/^west/north/p' datafile
范例7
将文件中所有两位数字结尾的行,在数字后面加上.5
sh-4.2# sed 's/[0-9][0-9]$/&.5/' datafile
范例8
文件中出现所有Hemenway的关键词都替换成Jones,只有发生改变的行才被打印。
sh-4.2# sed -n 's/Hemenway/Jones/gp' datafile
范例9
包含在圆括号里面的模式Mar作为标签1保存于特定的寄存器中。替换串可以通过1引用它,则Margot替换成Marianne。
sh-4.2# sed -n 's/(Mar)got/1ianne/p' datafile
范例10
紧跟在s命令后的字符就是查找串和替换串之间的分隔符。分隔符默认为正斜杠,但可以改变。无论什么字符(换行符、反斜杠除外),只要紧跟着s命令,就可以成为新的分隔符。这个方法在查找包含正斜杠的模式很方便,例如查找路劲或者日期。
sh-4.2# sed 's#3#88#g' datafile
范例11
打印模式'west'和模式'east'之间的所有行。如果west出现在east之后的某一行,则打印范围从west所在行开始,到下一个出现east的行或者文件末尾(如果前者未出现)
sh-4.2# sed -n '/west/,/east/p' datafile
范例12
打印从第五行到第一个以northeast开头的行之间的所有行。
sh-4.2# sed -n '5,/^northeast/p' datafile
范例13
修改模式'west'到模式'east'之间的所有行,将各行的行尾'$'替换成字符串'**VACA**'。换行符被移到这个新的字符串后面。
sh-4.2# sed '/west/,/east/ s/$/**VACA**/' datafile
范例14
选项-e用于进行多重编辑。第一重编辑删除1至3行。第二重编辑将Hemenway替换成Jones。因为是逐行进行这两项编辑(即这两个命令都在模式空间的当前行上执行),所以编辑命令的顺序会影响结果。例如,这两条命令执行的都是替换,则前一次替换会影响后一次替换。
sh-4.2# sed -e '1,3d' -e 's/Hemenway/Jones/' datafile
范例15
r命令读取文件的指定行。如果在文件datafile的某一行匹配到模式Suan,就在该行后读入文件newfile的内容。如果出现的Suan的不止一行,则出现在Suan的各个行后都读入newfile文件的内容。
# 示例文件 sh-4.2# cat newfile ---------------------------------------------- |*** SUAN HAS LEFT THE COMPANY*** | ---------------------------------------------- sh-4.2# sed '/Suan/r newfile' datafile
范例16
w命令把指定行写入文件。文件datafile中所有包含模式north的行都被写入到newfile中。
sh-4.2# sed -n '/north/w newfile' datafile
范例17
命令a用于追加。字符串--->THE NORTH SALES DISTRICT HAS MOVED<---被加在以north开头,north后跟一制表符的各行之后。用于追加的文本必须出现在追加命令的下一行上。sed要求a命令后跟一个反斜杠。如果要追加的内容不超过80个字符(即一行的最大内容),则除最后一行外,其他各行都必须用反斜杠结尾。
sh-4.2# sed '/^north /a --->THE NORTH SALES DISTRICT HAS MOVED<---' datafile 或者 sh-4.2# sed '/^north /a --->THE NORTH SALES DISTRICT HAS MOVED<---' datafile
范例18
命令i是插入命令。如果在某一行匹配到模式eastern,i命令就在该行的上方插入命令中反斜杠后的文本。除了最后一行,插入的文本每一行都必须以反斜杠结尾。
sh-4.2# sed '/eastern/i > NEW ENGLAND REGION > ----------------------------------------' datafile
范例19
命令c是修改命令。该命令将完整的修改在模式空间中的当前行。如果模式eastern被匹配,c命令将用反斜杠后的文本替换包含eastern的行。除了最后一行之外,反斜杠对每一行插入的行都是必要的。
sh-4.2# sed '/eastern/c > THE EASTERN REGION HAS BEEN TEMPORARILY CLOSED' datafile
范例20
如果在某一行匹配到模式eastern,n命令就指示sed用下一个输入行(即包含AM Main Jr.的那一行 )替换模式空间中的当前行,并用Archie替换该行中的AM,然后打印该行,再继续往下处理。
sh-4.2# sed '/eastern/{n; s/AM/Archie/;}' datafile 或者 sh-4.2# sed -e '/eastern/n' -e 's/AM/Archie/' datafile
范例21
y命令把第1至3行中的所有小写字母替换成大写字母。正则表达式元字符y命令不起作用。与替换分隔符一样,斜杠可以被替换成其他字符。
sh-4.2# sed '1,3y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' datafile 或者 sh-4.2# sed '1,3 s/[a-z]/u&/g' datafile
范例22
将文件中的所有小写字母转换成大写字母。
sh-4.2# sed 's/[a-z]/u&/g' datafile
说明:查找串中可以用正则表达式,但是替换串中不能用正则表达式,只能用u;
u就是表示把第一个字符转化成大写字母。
U就是表示所有的大写字母。
&表示匹配前面正则表达式的那部分。
范例23
将文件中所有的大写字母转换成小写字母。
sh-4.2# sed 's/[A-Z]/l&/g' datafile
说明
l就是表示将所有的大写字母转换成小写字母
L就是表示所有的小写字母。
范例24
打印完第五行之后,q命令让sed程序退出。
sh-4.2# sed '5q' datafile
范例25
匹配模式'Lewis',并且用Joseph替换,然后用q命令退出sed程序。
sh-4.2# sed '/Lewis/{s/Lewis/Joseph/;q;}' datafile
范例26
将模式'northeast'的行放入到最后一行显示
sh-4.2# sed -e '/northeast/h' -e '$G' datafile
说明
sed处理文件时,会把文件的每一行都保存到模式空间(临时缓冲区)中。sed处理完每一行后,都会将其打印到屏幕上,除非该行被删除或者取消打印。之后,模式空间会被清空,下一输入行被保存进来,等待处理。本例中,包含模式northeast的行被找到之后,就被存放到模式空间里,h命令把它复制并且保存到另外一个特殊的缓冲区,这个特殊的缓冲区成为暂存缓冲区。在第二条指令中,sed读到最后一行($)时,G命令指令指示它从暂存缓冲区中读取这一行,将其放回到模式空间中,追加在模式空间内当前行(即文本的最后一行)的后面。简而言之:所有包含模式northeast的行都会被复制到暂存缓冲区中,并且追加到文本的末尾。
范例27
将包含模式'WE'的行,放入到模式'CT'后显示
sh-4.2# sed -e '/WE/{h;d;}' -e '/CT/{G;}' datafile
说明
如果找到模式WE,h命令将从模式空间复制行到暂存缓冲区。之后d命令将包含WE模式的行全部删除,即不再显示它。第二条指令将查找模式CT,然后G命令取出之前存放在暂存缓冲区中的内容投放到CT模式后。
范例28
将包含模式'northeast'的行,存放到暂存缓冲区,并且替换显示到文本的最后一行
sh-4.2# sed -e '/northeast/h' -e '$g' datafile
说明
本例中,包含模式'northeast'的行会被h命令复制到暂存缓冲区。在第二条sed指令中,sed读取到最后一行($)时,g指令指示它从暂存缓冲区中读入行,并且将其放回到模式空间,替换掉模式空间内当前行。简而言之:包含'northeast'的行被复制并用来替换文件的最后一行。
范例29
将包含模式'WE'的行复制到模式空间并且删除,替换包含'CT'模式的最后一行(不指定,默认替换所有)。
sh-4.2# sed -e '/WE/{h;d;}' -e '/CT/{$g}' datafile
说明
如果找到模式WE,h命令就将其复制到暂存缓冲区。d命令将模式空间中的WE模式删除。若匹配模式CT,则g命令将获取暂存缓冲区的备份并覆盖模式空间中的当前行。简而言之:所有包含WE模式的行将转移到包含CT的行上,并进行覆盖。
范例30
包含Margot的行被包含Patricia的行替换。
sh-4.2# sed -e '/Patricia/{h;}' -e '/Margot/{x;}' datafile
sed练习题1
以dateboot文件内容为例,内容如下:
Steve Blenheim:238-923-7366:95 Latham Lane, Easton, PA 83755:11/12/56:20300 Betty Boop:245-836-8357:635 Cutesy Lane, Hollywood, CA 91464:6/23/23:14500 Igor Chevsky:385-375-8395:3567 Populus Place, Caldwell, NJ 23875:6/18/68:23400 Norma Corder:397-857-2735:74 Pine Street, Dearborn, MI 23874:3/28/45:245700 Jennifer Cowan:548-834-2348:583 Laurel Ave., Kingsville, TX 83745:10/1/35:58900 Jon DeLoach:408-253-3122:123 Park St., San Jose, CA 04086:7/25/53:85100 Karen Evich:284-758-2857:23 Edgecliff Place, Lincoln , NB 92743:7/25/53:85100 Karen Evich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200 Karen Evich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200 Fred Fardbarkle:674-843-1385:20 Parak Lane, Duluth, MN 23850:4/12/23:780900 Fred Fardbarkle:674-843-1385:20 Parak Lane, Duluth, MN 23850:4/12/23:780900 Lori Gortz:327-832-5728:3465 Mirlo Street, Peabody, MA 34756:10/2/65:35200 Paco Gutierrez:835-365-1284:454 Easy Street, Decatur, IL 75732:2/28/53:123500 Ephram Hardy:293-259-5395:235 CarltonLane, Joliet, IL 73858:8/12/20:56700 James Ikeda:834-938-8376:23445 Aster Ave., Allentown, NJ 83745:12/1/38:45000 Barbara Kertz:385-573-8326:832 Ponce Drive, Gzary, IN 83756:12/1/46:268500 Lesley Kirstin:408-456-1234:4 Harvard Square, Boston, MA 02133:4/22/62:52600 William Kopf:846-836-2837:6937 Ware Road, Milton, PA 93756:9/21/46:43500 Sir Lancelot:837-835-8257:474 Camelot Boulevard, Bath, WY 28356:5/13/69:24500 Jesse Neal:408-233-8971:45 Rose Terrace, San Francisco, CA 92303:2/3/36:25000 Zippy Pinhead:834-823-8319:2356 Bizarro Ave., Farmount, IL 84357:1/1/67:89500 Arthur Putie:923-835-8745:23 Wimp Lane, Kensington, DL 38758:8/31/69:126000 Popeye Sailor:156-454-3322:945 Bluto Street, Anywhere, USA 29358:3/19/35:22350 Jose Santiago:385-898-8357:38 Fife Way, Abilene, TX 39673:1/5/58:95600 Tommy Savage:408-724-0140:1222 Oxbow Court, Sunnyvale, CA 94087:5/19/66:34200 Yukio Takeshida:387-827-1095:13 Uno Lane, Ashville, NC 23556:7/1/29:57000 Vinh Tranh:438-910-7449:8235 Maple Street, Wilmington, VM 29085:9/23/63:68900
问题1:把Jon的名字改为Jonathan
sh-4.2# sed 's/Jon/Jonathan/' databook
问题2:删除头3行
sh-4.2# sed '1,3d' databook
问题3:打印第5~10行
sh-4.2# sed -n '5,10p' databook
问题4:删除含有Lane的所有行
sh-4.2# sed '/Lane/d' databook
问题5:打印所有生日在十一月或十二月的行
sh-4.2# sed -n '/:1[12]//p' databook
问题6:在以Karen开头的行末尾加上3颗星
sh-4.2# sed 's/^Karen.*$/&***/' databook
问题7:将所有包含Jose的行都替换为JOSE HAS RETIRED
sh-4.2# sed '/Jose/c JOSE HAS RETIRED' databook
问题8:把Popeye的生日改为11/14/46,假定您不知道Popeye的生日,设法用正则式查找出来
sh-4.2# sed -r -n -e '/Popeye/{s:[0-9]?+/[0-9]?+/[0-9]?+:11/14/46:;p}' databook
问题9:删除所有空行
sh-4.2# sed '/^$/d' databook
问题10:写一个能完成下列任务的sed脚本
- 在第一行上方插入标题PERSONNEL FILE.
- 删除以500结尾的工资项。
- 把名字和姓的内容颠倒后,打印文件内容。
- 在文件末尾加上THE END。
sh-4.2# sed -f sed databook sh-4.2# cat sed 1i PERSONNEL FILE s/[0-9]*500$// s/^(w*)s*(w*)/2 1/ $a THE END
sed练习题2
利用sed将下面文件全部在一行中打印输出。
sh-4.2# cat datafile 1.1.1.1 1.1.1.1 1.1.1.1 1.1.1.1 sed ":a;N;s/ //g;ta" datafile 1.1.1.1 1.1.1.1 1.1.1.1 1.1.1.1
说明
N; N是sed的一个处理命令,追加文本流中的下一行到模式空间进行合并处理,因此是换行符可见
:a和ta是配套使用,实现跳转功能。t是test测试的意思。
另外,还有:a和ba的配套使用方式,也可以实现跳转功能。b是branch分支的意思。
sed ":a;N;s/ //g;$!ba" datafile 1.1.1.1 1.1.1.1 1.1.1.1 1.1.1.1
awk的解决方案
awk 'BEGIN{ORS=" "}{print}END{print " "}' datafile
练习题3
利用sed将下面文件内容里面的空格全部替换成换行符
sh-4.2# cat datafile 1.1.1.1 1.1.1.1 1.1.1.1 1.1.1.1 sh-4.2# sed 's/ / /g' datafile