Sed初阶文档

sed可以充当一个行过滤器(与管道相接,从管道上游获得输入),或者从文件中获取其输入。输出将被放入到标准输出流。sed 将输出中的行加载到模式空间(pattern space),对模式空间的内容应用 sed 编辑命令,然后将模式空间写入到标准输出中。Sed 可以在模式空间中组合多个行,然后它可能将输出写入到文件中、只写入选择的输出,或者根本不执行写入。

Sed 使用正则表达式语法在模式空间中搜索并有选择地替换文本,以及决定对哪些文本行应用编辑命令。保持缓存为文本提供了临时存储。保持缓存可以取代模式空间、被添加到模式空间,或者与模式空间进行互换。Sed 提供了一组有限的命令,但是这些命令结合了正则表达式语法和保持缓存,因而实现了某些非常令人吃惊的功能。sed 命令集常常被称为 sed 脚本

举例说明sed的使用方法:

sed 's/a/A/' text1 #s命令表示替换,将text1每一行的第一个a替换为A

sed 's/a/A/g' text1 #加入g标记,表示将替换每一行的所有a

sed '2d;$s/a/A/g' text1 #2d表示删除第二行,;分隔了两个命令,第二个命令开始的$表示后续命令只操作最后一行

除了操作单独的行外(前面提到的$),sed 还可以操作一个行范围。行的起始和结束由一个逗号(,)分隔,并且可以被指定为行号、正则表达式或表示最后一行的美元符号($)。可以用大括号 { 和 } 对命令进行分组,使在大括号之间的命令只用于按范围选择的行。使用 -e 选项向脚本添加多个命令(实际上就是将命令分开,看起来更清楚,需要注意的事项是分隔开的地方不是任意的)。

sed -e '2,${' -e 's/a/A/g' -e '}' text1 #用-e选项来分段命令,2,$表明行范围,{}圈定行范围内的命令

sed -e '/pear/,/bana/{' -e 's/a/A/g' -e '}' text1 #/pear/,/bana/通过正则表达式指定行范围:从包含pear的行开始到包含bana的行结束(闭区间)

通过选项-f可以从文件读取命令

sed -f sedtab text1 #用sedtab文件中的字符串作为命令充当sed的命令对text1进行操作

sed '=' text2 #=命令输出行号,但是会将行号新起一行

sed '=' text2|sed 'N;s/\n//' #使用 N 命令将第二个输入行读取到模式空间,最后删除模式空间中两个行之间的换行符(\n)已经将不明白了,不得不看较全的sed教程

通用线程 -- sed 实例,第 1 部分

sed -e 'd' /etc/services

sed 打开 /etc/services 文件,1将一行读入其模式缓冲区,2执行编辑命令("删除行"),3然后打印模式缓冲区(缓冲区已为空)。然后,它对后面的每一行重复这些步骤。

sed -e '1d' /etc/services | more #删除第一行

sed -e '1,10d' /etc/services | more #删除[1,10]行

sed -e '/^#/d' /etc/services | more #删除以#开头的行

sed -n -e '/regexp/p' /path/to/my/test/file | more #-n表示除非有p选项在,否则不打印模式空间

sed -n -e '/BEGIN/,/END/p' /my/test/file | more #打印从包含 "BEGIN" 的行开始,并且以包含 "END" 的行结束的文本块

sed -n -e '/main[[:space:]]*(/,/^}/p' sourcefile.c | more #打印 C 源文件中的 main() 函数

通用线程 -- sed 实例,第 2 部分

在开始的时候先说一下和egrep的区别,可以使用扩展正则表达式,但是需要\来进行转义:

? + ( ) { } 

's///' 替换命令只是一个命令还可以与地址一起使用来控制要将命令应用到哪些行

sed -e 's/foo/bar/' myfile.txt #将 myfile.txt 中每行第一次出现的 'foo'(如果有的话)用字符串 'bar' 替换,然后将该文件内容输出到标准输出。

sed -e 's/foo/bar/g' myfile.txt #替换每行中的 所有出现

sed -e '1,10s/enchantment/entrapment/g' myfile2.txt #用短语 'entrapment' 替换所有出现的短语 'enchantment',但是只在第一到第十行(包括这两行)上这样做。

sed -e '/^$/,/^END/s/hills/mountains/g' myfile3.txt #用 'mountains' 替换 'hills',但是,只从空行开始,到以三个字符 'END' 开始的行结束(包括这两行)的文本块上这样做

sed -e 's:/usr/local:/usr:g' mylist.txt #使用冒号作为分隔符。如果需要在规则表达式中指定分隔符字符,可以在它前面加入反斜杠

sed -e 's/<.*>//g' myfile.html #匹配并删除 '<' 开始、到 '>' 结束、并且在其中包含任意数量字符的短语(它不会很好地工作)

sed -e 's/<[^>]*>//g' myfile.html #这样就对了

正则表达式的字符类(这些字符类应该被括在[]中)

[:alnum:]    字母数字 [a-z A-Z 0-9]

[:alpha:]    字母 [a-z A-Z]

[:blank:]    空格或制表键

[:cntrl:]    任何控制字符

[:digit:]    数字 [0-9]

[:graph:]    任何可视字符(无空格)

[:lower:]    小写 [a-z]

[:print:]    非控制字符

[:punct:]    标点字符

[:space:]    空格

[:upper:]    大写 [A-Z]

[:xdigit:]    十六进制数字 [0-9 a-f A-F]

sed -e 's/.*/ralph said: &/' origmsg.txt #&表示被正则表达式匹配的部分

sed -e 's/\(.*\) \(.*\) \(.*\)/Victor \1-\2 Von \3/' myfile.txt #实现把 "eeny meeny miny" 替换成 "Victor eeny-meeny Von miny" 的功能

sed -n -e '=;p' myfile.txt #'=' 命令告诉 sed 打印行号,'p' 命令明确告诉 sed 打印该行(因为处于 '-n' 模式),分号分隔命令

sed -n -e '=' -e 'p' myfile.txt #完成上个命令同样的效果

sed -n -f mycommands.sed myfile.txt #处理文件中书写的命令

1,20{s/[Ll]inux/GNU\/Linux/g;s/samba/Samba/g;s/posix/POSIX/g } #所有的行都会通过过滤器,但是只会处理1,20

i\ This line will be inserted before each line #每行前面添一行把一行或多行插入到模式空间中的当前行之后

c\ You're history, original line! Muhahaha! #"更改行"命令将实际 替换模式空间中的当前行

通用线程 -- sed 实例,第 3 部分

sed -e 's/$/\r/' myunix.txt > mydos.txt #将UNIX 风格的文本转换成 DOS/Windows 格式。基于 DOS/Windows 的文本文件在每一行末尾有一个 CR(回车)和 LF(换行),而 UNIX 文本只有一个换行

sed -e 's/.$//' mydos.txt > myunix.txt #将dos/windows风格文本风格变成unix风格,注意.$表示行末前的那个字符,当然就是那个\r了,然后替换为无物,就是删除

sed -e '1!G;h;$!d' forward.txt > backward.txt #实现反转行,即是tac的功能,解释如下:

如果把模式空间命名为M,保留空间命名为R,当前输入行命名为NL,那么做的功能(用伪代码表示)就是:

while has new input//一次读入一行(sed默认操作)

    M = NL;//从标准输入读入的一行赋值给模式空间(sed默认操作)

    if NL is not the first line//如果不是第一行

        M += R;//将保存空间附加给模式空间

    R = M;//将模式空间赋值给保存空间

    if NL is not the last line//如果不是最后一行

        M = emptyline;//清空模式空间,实际上是赋值为一个空行(空行就是清空d的操作)

    print M;//输出模式空间(sed默认操作)

R的初始值应该是一个空行

posted on 2011-10-08 16:24  Observer  阅读(475)  评论(0编辑  收藏  举报

导航