一、SED的特点:sed是一个流编辑器,非交互式,不影响编辑的源文件。sed分为好多个版本,但大多数支持主流的正则表达式(对正则表达式中的元字符支持的比较少,支持一部分)。每个unix或者linux版本都带有sed。[root@ /UNIX]# sed --versionGNU sed version 4.2.1Copyright (C) 2009 Free Software Foundation, Inc.二、sed的工作方式:一行一行的处理输入的文本,每一行首先被放入临时的缓存(也可以叫模式空间pattern space),然后处理完成后或者重定向到另一个位置(一个新文件)或者打印到屏幕(默认),然后从缓存移除该行,然后接着处理下一行,直到处理完成。三、sed的返回值:csh echo $statusbash echo $?返回值(各个版本不太一样,我测试的版本是这样的):0 -- 表示找到或者未找到,未发生错误1 -- 出错,包括语法错误、正则错误等[root@ /UNIX]# sed -n '/root/p' /etc/passwdroot:*:0:0:Charlie &:/root:/usr/local/bin/bashtoor:*:0:0:Bourne-again Superuser:/root:daemon:*:1:1:Owner of many system processes:/root:/usr/sbin/nologin[root@ /UNIX]# echo $?0[root@ /UNIX]# sed -n '/root/xx' /etc/passwdsed: -e expression #1, char 8: extra characters after command[root@ /UNIX]# echo $?1三、sed的语法:sed [选项] '/[正则表达式]/[命令]' 带处理的文本 [ [> 新文本] | [下一个命令] ]sed -n '/RE/p' filenamesed -n 's/RE/replacement String/g' filename四、sed中的元字符^ 行首 /^love/ 匹配以love开始的行$ 行尾 /love$/ 匹配以love结尾的行. 匹配一个字符,但是不是新的行的字符 /L..e/ 匹配以L开始,后面跟2个字符,最后跟一个e* 粘帖前一个字符,0个或者多个前一字符 / *love/ 匹配0个或者多个空格,后面跟love[] 匹配[]中的任意一个字符 /[Ll]ove/匹配love或者Love\(\) 分组,从左到右编号,最多有9个分组,第一个分组为1,用\1表示 s/\(love\)able/\1er/ 替换loveable为lover& 存储找到的字符 s/love/**&**/ 替换love为**love**\\> 单词结尾 /love\>/匹配以love结尾的单词x\{m\} 粘帖前一个字符或者分组,m次重复x\{m,\} 粘帖前一个字符或者分组,至少m次重复,多者不限x\{m,n\} 粘帖前一个字符或者分组,至少m次重复,但不超过n次注:在sed中\w \d \s 这些元字符不支持。[root@ /UNIX]# /usr/bin/sed.bak 's/\d\{2\}$/&.5/' datafile1:northwest NW Charles Main 3.0 .98 3 342:western WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 13[root@ /UNIX]# /usr/bin/sed.bak 's/[0-9][0-9]$/&.5/' datafile1:northwest NW Charles Main 3.0 .98 3 34.52:western WE Sharon Gray 5.3 .97 5 23.53:southwest SW Lewis Dalsass 2.7 .8 2 18.54:southern SO Suan Chin 5.1 .95 4 15.55:southeast SE Patricia Hemenway 4.0 .7 4 17.56:eastern EA TB Savage 4.4 .84 5 20.57:northeast NE AM Main Jr. 5.1 .94 3 13.58:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 13.5sed中默认使用"/"作为分界线,但是在s命令的时候,可以进行替换sed -n '\cREcp' fiename 使用c作为分界线五、定址:sed使用定址的方式处理行,定址可以使用行号(从1开始)或者正则表达式定址,也可以使用两种方式的组合,如果不定址,就处理全文。sed '1, 3d' myfile 三次1~3行sed -n '/[Jj]ohn/p' datafile 打印包含john/John的行六、sed的命令有十几个,s、a\、c\、d、p、r、!等,下面逐一举例说明:p(print)命令:一般和选项-n 一起使用,打印选择的行sed -n '/north/p' datafile打印包含north的行,如果不使用-n,就把全文打出来的同时,在匹配的行下面再打印一次匹配行。d(delete)命令:删除匹配的行后打印其他剩余的行sed '3d' datafile 删除第三行,剩余行打印sed '3,$d' datafile 删除3到最后一行,剩余的行打印sed '$d' datafile 删除最后一行sed '1d' datafile 删除第一行sed '/north/d' datafile 删除包含north的行,其他行打印出来s(substitution)替换命令:替换找到的模式为新的字符,如果使用g,所有匹配都替换,否则只替换行中找到的第一个sed 's/west/north/g' datafile全行替换west为north,不加g选项,即使一行中出现若干次的west,只替换第一个。sed -n 's/^west/north/p' datafile[root@ /UNIX]# sed -n 's/west/north/gp' datafile1:northnorth NW Charles Main 3.0 .98 3 342:northern WE Sharon Gray 5.3 .97 5 233:southnorth SW Lewis Dalsass 2.7 .8 2 18sed找到west,并替换为north,打印这些替换的行。[root@ /UNIX]# sed -n 's/\(Mar\)got/\1ianne/p' datafile8:north NO Marianne Weber 4.5 .89 5 9用\1表示找到的的第一个模式Margot的Mar部分,并替换为将Mar部分后面加ianne。在s命令中使用其他界定符s命令使用新的字符串替换匹配字符串,默认的界定符是“/”,但是如果你喜欢或者处于查找默认界定符的目的你可以使用别的界定符。sed 's#3#88#g' datafile[root@ /UNIX]# sed -n 's#north#liujun#pg' datafile1:liujunwest NW Charles Main 3.0 .98 3 347:liujuneast NE AM Main Jr. 5.1 .94 3 138:liujun NO Margot Weber 4.5 .89 5 9[root@ /UNIX]# cat datafile1:northwest NW Charles Main 3.0 .98 3 342:western WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 1310:liujun LJ 10/10/1981 4.0 .88 3 20[root@ /UNIX]# sed -n 's#10/10/1981#1/1/81#pg' datafile10:liujun LJ 1/1/81 4.0 .88 3 20sed可以通过逗号","来界定一个选择的范围进行处理,这个范围开始与某一个地址,结束于另一个地址。地址的范围可以使用行号(如:5,10)来界定,也可以使用正则表达式界定(如:/Dick/,/Joe/),也可以使用这两种的混合方式(如:5,$或者/north/, 7)。选择的范围包括起始行及中间的所有行。如果结束的范围没有到达,就一直处理到结束行;如果结束行到达,那么在剩余的部分继续开始匹配新的起始行。[root@ /UNIX]# cat datafile | sed '5i\11:northAddNewLine NL NewLineAdd' | sed -n '/north/,/south/p'1:northwest NW Charles Main 3.0 .98 3 342:western WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 1811:northAddNewLine NL NewLineAdd5:southeast SE Patricia Hemenway 4.0 .7 4 177:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 1310:liujun LJ 10/10/1981 4.0 .88 3 20这里有3个符号条件的选择范围1~3,11~5和7~$,因为第三个范围没有找到south,所以直到所有行完成。[root@ /UNIX]# sed -n '5,/^[0-9]:northeast/p' datafile5:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE AM Main Jr. 5.1 .94 3 13打印从第5行开始到以一个数字开始,后面跟一个冒号(:),再跟northeast的行,把这些选择的行打印出来。[root@ /UNIX]# sed -n '/west/,/east/s/$/**VACA**/p' datafile1:northwest NW Charles Main 3.0 .98 3 34**VACA**2:western WE Sharon Gray 5.3 .97 5 23**VACA**3:southwest SW Lewis Dalsass 2.7 .8 2 18**VACA**4:southern SO Suan Chin 5.1 .95 4 15**VACA**5:southeast SE Patricia Hemenway 4.0 .7 4 17**VACA**选择匹配模式,然后替换行尾为**VACA**e命令(用于多重编辑):对于在模式空间中的某一行,如果需要执行多个sed命令,可以使用-e注意:多重编辑中,p命令和其他如:d、s命令不能同时[root@ /UNIX]# sed -ne '1d' -e '/west/,/south/p' datafile2:western WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 18[root@ /UNIX]# sed -ne '1d' -e '/west/,/south/p' -e '/west/,/south/d' datafile2:western WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 18上面这个例子中,第三次编辑删除d命令并不起作用,这是因为,第二重编辑已经把内容打印出来了,你删除只是删除了模式空间中的,打印出来的没法删除了(因为已经打印在屏幕上了)。所以这样的用法也是错的:[root@ /UNIX]# sed -ne '/west/, /south/p' -ne 's/west/WEST/p' datafile1:northwest NW Charles Main 3.0 .98 3 341:northWEST NW Charles Main 3.0 .98 3 342:western WE Sharon Gray 5.3 .97 5 232:WESTern WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 183:southWEST SW Lewis Dalsass 2.7 .8 2 18sed -e '/west/, /south/{s/west/WEST/p}' datafiler(read)读命令:[root@ /UNIX]# cat newfile1:northwest NW Charles Main 3.0 .98 3 347:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 9[root@ /UNIX]# sed -e '/Suan/r newfile' datafile1:northwest NW Charles Main 3.0 .98 3 342:western WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 151:northwest NW Charles Main 3.0 .98 3 347:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 95:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 1310:liujun LJ 10/10/1981 4.0 .88 3 20找到匹配的模式,然后读取一个文件到匹配模式下面的行,然后继续显示其他剩余行。如果找到多次,会多次读入该文件的内容。w(write)写命令:sed虽然不会影响自身编辑的文件,但是可以使用w创建新的文件。[root@ /UNIX]# ls -l newFilels: newFile: No such file or directory[root@ /UNIX]# sed -n '/south/w newFile' datafile[root@ /UNIX]# cat newFile3:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 17a\(append)追加命令:在找到匹配模式的下面,写入新的内容,这个命令和读差不多,区别是:r命令是读一个文件,a命令是读入新的行,这行的内容可以直接在命令行提供,而不是读取另外一个文件。csh需要使用a\\,如果插入的行是多行,除最后一行外,其他行需要用\结尾。[root@ /UNIX]# sed -e '/north/a\\------------>edit> liujun \@ 2011.4' datafile1:northwest NW Charles Main 3.0 .98 3 34------------>editliujun @ 2011.42:western WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE AM Main Jr. 5.1 .94 3 13------------>editliujun @ 2011.48:north NO Margot Weber 4.5 .89 5 9------------>editliujun @ 2011.49:central CT Ann Stephens 5.7 .94 5 1310:liujun LJ 10/10/1981 4.0 .88 3 20i\(insert)插入命令:这个命令和a\相似,区别是:插入是在匹配模式的前面,而不是后面。[root@ /UNIX]# sed -e '/north/i\\------------>editliujun \@ 2011.4' datafile------------>editliujun @ 2011.41:northwest NW Charles Main 3.0 .98 3 342:western WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 20------------>editliujun @ 2011.47:northeast NE AM Main Jr. 5.1 .94 3 13------------>editliujun @ 2011.48:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 1310:liujun LJ 10/10/1981 4.0 .88 3 20c(change)改变当前行内容命令:[root@ /UNIX]# sed -e '/eastern/c\&**ch**' datafile1:northwest NW Charles Main 3.0 .98 3 342:western WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 17&**ch**7:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 1310:liujun LJ 10/10/1981 4.0 .88 3 20这里&并不起作用,在s命令中&是找到的匹配字符串[root@ /UNIX]# sed -n 's/eastern/&:I GOT IT/p' datafile6:eastern:I GOT IT EA TB Savage 4.4 .84 5 20n(next)下一行命令和q(quit)退出处理命令:找到匹配行后执行n,会读取匹配行的下一行到模式空间中,并在这行上执行命令。[root@ /UNIX]# sed '/eastern/{n;s/AM/Archie/;q;}' datafile1:northwest NW Charles Main 3.0 .98 3 342:western WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE Archie Main Jr. 5.1 .94 3 13先匹配包含eastern的行,找到以后直接跳到下一行执行替换命令s,执行完成后退出q。y(translation)逐字转换命令,类似tr命令[root@ /UNIX]# echo "linux" | tr "[:lower:]" "[:upper:]"LINUX[root@ /UNIX]# echo "abc" | tr "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"ABC[root@ /UNIX]# sed '1,3y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' datafile1:NORTHWEST NW CHARLES MAIN 3.0 .98 3 342:WESTERN WE SHARON GRAY 5.3 .97 5 233:SOUTHWEST SW LEWIS DALSASS 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 1310:liujun LJ 10/10/1981 4.0 .88 3 20h(hold)和g(get)命令h命令将当前处理的行从模式空间放到另外一个holding缓存中,g命令可以取出来。[root@ /UNIX]# sed -e '/northeast/h' -e '$G' datafile1:northwest NW Charles Main 3.0 .98 3 342:western WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 1310:liujun LJ 10/10/1981 4.0 .88 3 207:northeast NE AM Main Jr. 5.1 .94 3 13[root@ /UNIX]# sed -e '/northeast/h' -e '$g' datafile1:northwest NW Charles Main 3.0 .98 3 342:western WE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 137:northeast NE AM Main Jr. 5.1 .94 3 13取出命令有g和G两种模式,G取出后,追加到指定位置,而g替换掉指定位置。[root@ /UNIX]# sed -e '/WE/{h;d}' -e '4G' datafile1:northwest NW Charles Main 3.0 .98 3 343:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 152:western WE Sharon Gray 5.3 .97 5 235:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 1310:liujun LJ 10/10/1981 4.0 .88 3 20[root@ /UNIX]# sed -e '{h;}' -e 'g;s/WE/EWE/;' datafile1:northwest NW Charles Main 3.0 .98 3 342:western EWE Sharon Gray 5.3 .97 5 233:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 1310:liujun LJ 10/10/1981 4.0 .88 3 20[root@ /UNIX]# sed -e '/WE/{h;d}' -e '/CT/{G;}' datafile1:northwest NW Charles Main 3.0 .98 3 343:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 99:central CT Ann Stephens 5.7 .94 5 132:western WE Sharon Gray 5.3 .97 5 2310:liujun LJ 10/10/1981 4.0 .88 3 20x(exchange)交换命令,将当前holding缓存中的内容和模式空间中的内容交换。[root@ /UNIX]# sed -e '/WE/{h;d;}' -e '/CT/{x;}' -ne '{$G;p;}' datafile1:northwest NW Charles Main 3.0 .98 3 343:southwest SW Lewis Dalsass 2.7 .8 2 184:southern SO Suan Chin 5.1 .95 4 155:southeast SE Patricia Hemenway 4.0 .7 4 176:eastern EA TB Savage 4.4 .84 5 207:northeast NE AM Main Jr. 5.1 .94 3 138:north NO Margot Weber 4.5 .89 5 92:western WE Sharon Gray 5.3 .97 5 2310:liujun LJ 10/10/1981 4.0 .88 3 209:central CT Ann Stephens 5.7 .94 5 13先找到WE,匹配后放到holding缓存,然后删除模式空间中的行;再找CT,匹配后和当前模式空间中的行(第9行包含CT的行)和holding缓存中的行交换,即:将holding缓存中的行显示到第9行的位置;然后从holding缓存中读取行(及包含CT的那行),放到所有行的末尾,打印到屏幕上。(END) 02-12 07:40