Linux的简单shell脚本中修改文件操作
Linux Shell常用技巧(三) sed
八、流编辑器sed
8.1 sed简介
sed是stream editor的缩写,一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。sed主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等。
8.2 sed命令格式
sed [nefri] 'command' file(s)
常用选项:
-n使用安静(silent)模式。在一般sed的用法中,所有来自stdin的资料一般都会被列出到屏幕,但如果加上-n参数后,则只有经过sed特殊处理的那一行(或者command)才会被列出来。
-e允许多点编辑。
-f直接将sed的动作写在一个档案内,-f filename 则可以执行filename内的sed动作。
-rsed 的动作支援的是延伸型正规表示法的语法。(预设是基础正规表示法语法)
-i直接修改读取的档案内容,而不是由屏幕输出。
常用command:
a\新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c\取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i\插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起运作~
s取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!
高级command:
需要说明的是,sed中的正则和grep的基本相同,完全可以参照本系列的第一篇中的详细说明。
8.3 sed实例
# cat testfile
northwest NWCharles Main 3.0.983 34western WESharon Gray5.3.975 23southwest SWLewis Dalsass 2.7.8 2 18southern SOSuan Chin 5.1.954 15southeast SEPatricia Hemenway 4.0.7 4 17eastern EATB Savage 4.4.845 20northeast NEAM Main Jr.5.1.943 13north NOMargot Weber 4.5.895 9central CTAnn Stephens 5.7.945 13
实例1.1:如果模板north被找到,sed除了打印所有行之外,还有打印匹配行。
# sed '/north/p' testfile
northwest NWCharles Main 3.0.983 34northwest NWCharles Main 3.0.983 34western WESharon Gray5.3.975 23southwest SWLewis Dalsass 2.7.82 18southern SOSuan Chin 5.1.954 15southeast SEPatricia Hemenway 4.0.74 17eastern EATB Savage 4.4.845 20northeast NEAM Main Jr.5.1.943 13northeast NEAM Main Jr.5.1.943 13north NOMargot Weber 4.5.895 9north NOMargot Weber 4.5.895 9central CTAnn Stephens 5.7.945 13
实例1.2:-n选项取消了sed的默认行为。在没有-n的时候,包含模板的行被打印两次,但是在使用-n的时候将只打印包含模板的行。
# sed -n '/north/p' testfile
northwest NWCharles Main 3.0.983 34northeast NEAM Main Jr.5.1.943 13north NOMargot Weber 4.5.895 9
实例:列出第5-7行
# nl testfile |sed -n '5,7p'
5 southeast SEPatricia Hemenway 4.0.74 176 eastern EATB Savage 4.4.845 207 northeast NEAM Main Jr.5.1.943 13
实例2.1:删除第三行,其他行默认输出到屏幕。
# nl testfile |sed '3d'
1 northwest NWCharles Main 3.0.983 342 western WESharon Gray5.3.975 234 southern SOSuan Chin 5.1.954 155 southeast SEPatricia Hemenway 4.0.74 176 eastern EATB Savage 4.4.845 207 northeast NEAM Main Jr.5.1.943 138 north NOMargot Weber 4.5.895 99 central CTAnn Stephens 5.7.945 13
实例2.2:删除2~5行
# nl testfile |sed '2,5d'
1 northwest NWCharles Main 3.0.983 346 eastern EATB Savage 4.4.845 207 northeast NEAM Main Jr.5.1.943 138 north NOMargot Weber 4.5.895 99 central CTAnn Stephens 5.7.945 13
实例2.3:从第三行删除到最后一行,其他行被打印。$表示最后一行。
# nl testfile |sed '3,$d'
1 northwest NWCharles Main 3.0.983 342 western WESharon Gray5.3.975 23
实例2.4:删除最后一行,其他行打印。
# nl testfile |sed '$d'
1 northwest NWCharles Main 3.0.983 342 western WESharon Gray5.3.975 233 southwest SWLewis Dalsass 2.7.82 184 southern SOSuan Chin 5.1.954 155 southeast SEPatricia Hemenway 4.0.74 176 eastern EATB Savage 4.4.845 207 northeast NEAM Main Jr.5.1.943 138 north NOMargot Weber 4.5.895 9
实例2.5:删除所有包含north的行,其他行打印。
# nl testfile |sed '/north/d'
2 western WESharon Gray5.3.975 233 southwest SWLewis Dalsass 2.7.82 184 southern SOSuan Chin 5.1.954 155 southeast SEPatricia Hemenway 4.0.74 176 eastern EATB Savage 4.4.845 209 central CTAnn Stephens 5.7.945 13
实例3.1:在第二行后(即加在第三行)加上"United States"。
# nl testfile |sed '2a United States'
1 northwest NWCharles Main 3.0.983 342 western WESharon Gray5.3.975 23United States3 southwest SWLewis Dalsass 2.7.82 184 southern SOSuan Chin 5.1.954 155 southeast SEPatricia Hemenway 4.0.74 176 eastern EATB Savage 4.4.845 207 northeast NEAM Main Jr.5.1.943 138 north NOMargot Weber 4.5.895 99 central CTAnn Stephens 5.7.945 13
如果要在第二行前加,则命令为
# nl testfile |sed '2i United States'
实例3.2:在第二行后加上两行文本。
# nl testfile |sed '2a United States \
> America'
1 northwest NWCharles Main 3.0.983 342 western WESharon Gray5.3.975 23United States America3 southwest SWLewis Dalsass 2.7.82 184 southern SOSuan Chin 5.1.954 155 southeast SEPatricia Hemenway 4.0.74 176 eastern EATB Savage 4.4.845 207 northeast NEAM Main Jr.5.1.943 138 north NOMargot Weber 4.5.895 99 central CTAnn Stephens 5.7.945 13
若要新增两行,则每一行之间都必须要以反斜线“\”来进行新行的增加。
实例4.1:将第2~5行的内容取代为“No 2-5 number”。
# nl testfile |sed '2,5c No 2-5 number'
1 northwest NWCharles Main 3.0.983 34No 2-5 number6 eastern EATB Savage 4.4.845 207 northeast NEAM Main Jr.5.1.943 138 north NOMargot Weber 4.5.895 99 central CTAnn Stephens 5.7.945 13
实例3.1:s表示替换,g表示命令作用于整个当前行。如果该行存在多个west,都将被替换为north,如果没有g,则只是替换第一个匹配。
格式:sed's/要替换的字符串/新的字符串/g'
# nl testfile |sed 's/west/north/g'
1 northnorth NWCharles Main 3.0.983 342 northern WESharon Gray5.3.975 233 southnorth SWLewis Dalsass 2.7.82 184 southern SOSuan Chin 5.1.954 155 southeast SEPatricia Hemenway 4.0.74 176 eastern EATB Savage 4.4.845 207 northeast NEAM Main Jr.5.1.943 138 north NOMargot Weber 4.5.895 99 central CTAnn Stephens 5.7.945 13
实例3.2:-n表示只打印匹配行,如果某一行的开头是west,则替换为north。
# sed -n 's/^west/north/p' testfile
northern WESharon Gray5.3.975 23
实例3.3:&符号表示替换字符串中被找到的部分。所有以两个数字结束的行,最后的数字都将被它们自己替换,同时追加.5。
# nl testfile |sed 's/[0-9][0-9]$/&.5/'
1 northwest NWCharles Main 3.0.983 34.52 western WESharon Gray5.3.975 23.53 southwest SWLewis Dalsass 2.7.82 18.54 southern SOSuan Chin 5.1.954 15.55 southeast SEPatricia Hemenway 4.0.74 17.56 eastern EATB Savage 4.4.845 20.57 northeast NEAM Main Jr.5.1.943 13.58 north NOMargot Weber 4.5.895 99 central CTAnn Stephens 5.7.945 13.5
实例3.4:所有的Hemenway被替换为Jones。-n选项加p命令则表示只打印匹配行。
# nl testfile |sed -n 's/Hemenway/Jones/gp'
5 southeast SEPatricia Jones 4.0.74 17
实例3.5:模板Mar被包含在一对括号中,并在特殊的寄存器中保存为tag 1,它将在后面作为\1替换字符串,Margot被替换为Marlianne。
# nl testfile |sed -n 's/\(Mar\)got/\1lianne/p'
8 north NOMarlianne Weber 4.5.895 9
实例3.6:s后面的字符一定是分隔搜索字符串和替换字符串的分隔符,默认为斜杠,但是在s命令使用的情况下可以改变。不论什么字符紧跟着s命令都认为是新的分隔符。这个技术在搜索含斜杠的模板时非常有用,例如搜索时间和路径的时候。
# sed 's#3#88#g' testfile
northwest NWCharles Main 88.0.9888 884western WESharon Gray5.88.975 288southwest SWLewis Dalsass 2.7.82 18southern SOSuan Chin 5.1.954 15southeast SEPatricia Hemenway 4.0.74 17eastern EATB Savage 4.4.845 20northeast NEAM Main Jr.5.1.9488 188north NOMargot Weber 4.5.895 9central CTAnn Stephens 5.7.945 188
# sed 's@3@88@g' testfile
northwest NWCharles Main 88.0.9888 884western WESharon Gray5.88.975 288southwest SWLewis Dalsass 2.7.82 18southern SOSuan Chin 5.1.954 15southeast SEPatricia Hemenway 4.0.74 17eastern EATB Savage 4.4.845 20northeast NEAM Main Jr.5.1.9488 188north NOMargot Weber 4.5.895 9central CTAnn Stephens 5.7.945 188
实例3.7:所有在模板west和east所确定的范围内的行都被打印,如果west出现在east后面的行中,从west开始到下一个east,无论这个 east出现在哪里,二者之间的行都被打印,即使从west开始到文件的末尾还没有出现east,那么从west到末尾的所有行都将打印。
# nl testfile |sed -n '/south/,/east/p'
3 southwest SWLewis Dalsass 2.7.82 184 southern SOSuan Chin 5.1.954 155 southeast SEPatricia Hemenway 4.0.74 17
实例3.8:打印从第五行开始到第一个以northeast开头的行之间的所有行。
# sed -n '5,/^northeast/p' testfile
southeast SEPatricia Hemenway 4.0.74 17eastern EATB Savage 4.4.845 20northeast NEAM Main Jr.5.1.943 13
实例3.9:-e选项表示多点编辑。第一个编辑命令是删除第一到第三行。第二个编辑命令是用Jones替换Hemenway。
# nl testfile |sed -e '1,3d' -e 's/Hemenway/Jones/'
4 southern SOSuan Chin 5.1.954 155 southeast SEPatricia Jones 4.0.74 176 eastern EATB Savage 4.4.845 207 northeast NEAM Main Jr.5.1.943 138 north NOMargot Weber 4.5.895 99 central CTAnn Stephens 5.7.945 13
实例3.10:将所有匹配含有north的行写入newfile中。
# sed -n '/north/w newfile' testfile
# cat newfile
northwest NWCharles Main 3.0.983 34northeast NEAM Main Jr.5.1.943 13north NOMargot Weber 4.5.895 9
实例4.1:i是插入命令,在匹配模式行前插入文本。
# sed '/eastern/i\NEW ENGLAND REGION' testfile
northwest NWCharles Main 3.0.983 34western WESharon Gray5.3.975 23southwest SWLewis Dalsass 2.7.82 18southern SOSuan Chin 5.1.954 15southeast SEPatricia Hemenway 4.0.74 17NEW ENGLAND REGIONeastern EATB Savage 4.4.845 20northeast NEAM Main Jr.5.1.943 13north NOMargot Weber 4.5.895 9central CTAnn Stephens 5.7.945 13
实例5.1:找到匹配模式eastern的行后,执行后面花括号中的一组命令,每个命令之间用逗号分隔,n表示定位到匹配行的下一行,s/AM/Archie/完成Archie到AM的替换,p和-n选项的合用,则只是打印作用到的行。
# sed -n '/eastern/{n;s/AM/Archie/;p}' testfile
northeast NEArchie Main Jr.5.1.943 13
实例:-e表示多点编辑,第一个编辑命令y将前三行中的所有小写字母替换为大写字母,-n表示不显示替换后的输出,第二个编辑命令将只是打印输出转换后的前三行。注意y不能用于正则。
# sed -n -e '1,3y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' -e '1,3p' testfile
NORTHWEST NWCHARLES MAIN 3.0.983 34WESTERN WESHARON GRAY5.3.975 23SOUTHWEST SWLEWIS DALSASS 2.7.82 18
实例:打印完第二行后退出。
# sed '2q' testfile
northwest NWCharles Main 3.0.983 34western WESharon Gray5.3.975 23
实例:当模板Lewis在某一行被匹配,替换命令首先将Lewis替换为Joseph,然后再用q退出sed。
# sed '/Lewis/{s/Lewis/Joseph/;q;}' testfile
northwest NWCharles Main 3.0.983 34western WESharon Gray5.3.975 23southwest SWJoseph Dalsass 2.7.82 18
实例:在sed处理文件的时候,每一行都被保存在pattern space的临时缓冲区中。除非行被删除或者输出被取消,否则所有被处理过的行都将打印在屏幕上。接着pattern space被清空,并存入新的一行等待处理。在下面的例子中,包含模板的northeast行被找到,并被放入pattern space中,h命令将其复制并存入一个称为holding buffer的特殊缓冲区内。在第二个sed编辑命令中,当达到最后一行后,G命令告诉sed从holding buffer中取得该行,然后把它放回到pattern space中,且追加到现在已经存在于模式空间的行的末尾。
# sed -e '/northeast/h' -e '$G' testfile
northwest NWCharles Main 3.0.983 34western WESharon Gray5.3.975 23southwest SWLewis Dalsass 2.7.82 18southern SOSuan Chin 5.1.954 15southeast SEPatricia Hemenway 4.0.74 17eastern EATB Savage 4.4.845 20northeast NEAM Main Jr.5.1.943 13north NOMargot Weber 4.5.895 9central CTAnn Stephens 5.7.945 13northeast NEAM Main Jr.5.1.943 13
实例:如果模板WE在某一行被匹配,h命令将使得该行从pattern space中复制到holding buffer中,d命令在将该行删除,因此WE匹配行没有在原来的位置被输出。第二个命令搜索CT,一旦被找到,G命令将从holding buffer中取回行,并追加到当前pattern space的行末尾。简单的说,WE所在的行被移动并追加到包含CT行的后面。
# sed -e '/WE/{h;d;}' -e '/CT/{G;}' testfile
northwest NWCharles Main 3.0.983 34southwest SWLewis Dalsass 2.7.82 18southern SOSuan Chin 5.1.954 15southeast SEPatricia Hemenway 4.0.74 17eastern EATB Savage 4.4.845 20northeast NEAM Main Jr.5.1.943 13north NOMargot Weber 4.5.895 9central CTAnn Stephens 5.7.945 13western WESharon Gray5.3.975 23
实例:第一个命令将匹配northeast的行从pattern space复制到holding buffer,第二个命令在读取的文件的末尾时,g命令告诉sed从holding buffer中取得行,并把它放回到pattern space中,以替换已经存在于pattern space中的。简单说就是包含模板northeast的行被复制并覆盖了文件的末尾行。
# sed -e '/northeast/h' -e '$g' testfile
northwest NWCharles Main 3.0.983 34western WESharon Gray5.3.975 23southwest SWLewis Dalsass 2.7.82 18southern SOSuan Chin 5.1.954 15southeast SEPatricia Hemenway 4.0.74 17eastern EATB Savage 4.4.845 20northeast NEAM Main Jr.5.1.943 13north NOMargot Weber 4.5.895 9northeast NEAM Main Jr.5.1.943 13
实例:模板WE匹配的行被h命令复制到holding buffer,再被d命令删除。结果可以看出WE的原有位置没有输出。第二个编辑命令将找到匹配CT的行,g命令将取得holding buffer中的行,并覆盖当前pattern space中的行,即匹配CT的行。简单的说,任何包含模板northeast的行都将被复制,并覆盖包含CT的行。
# sed -e '/WE/{h;d;}' -e '/CT/{g;}' testfile
northwest NWCharles Main 3.0.983 34southwest SWLewis Dalsass 2.7.82 18southern SOSuan Chin 5.1.954 15southeast SEPatricia Hemenway 4.0.74 17eastern EATB Savage 4.4.845 20northeast NEAM Main Jr.5.1.943 13north NOMargot Weber 4.5.895 9western WESharon Gray5.3.975 23
实例:第一个编辑中的h命令将匹配Patricia的行复制到holding buffer中,第二个编辑中的x命令,会将holding buffer中的文本考虑到pattern space中,而pattern space中的文本被复制到holding buffer中。因此在打印匹配Margot行的地方打印了holding buffer中的文本,即第一个命令中匹配Patricia的行文本,第三个编辑命令会将交互后的holding buffer中的文本在最后一行的后面打印出来。
# sed -e '/Patricia/h' -e '/Margot/x' -e '$G' testfile
northwest NWCharles Main 3.0.983 34western WESharon Gray5.3.975 23southwest SWLewis Dalsass 2.7.82 18southern SOSuan Chin 5.1.954 15southeast SEPatricia Hemenway 4.0.74 17eastern EATB Savage 4.4.845 20northeast NEAM Main Jr.5.1.943 13southeast SEPatricia Hemenway 4.0.74 17central CTAnn Stephens 5.7.945 13north NOMargot Weber 4.5.895 9
posted on -04-01 13:27菜问问 阅读(...) 评论(...) 编辑 收藏