每周一荐:流编辑器sed
做网络游戏服务器端,最烦人的就是查后台日志。外面的玩家报BUG或者其他异常的时候,客服搞不定的时候,就需要服务器的程序去查日志。分析日志需要一些比较好的文本分析工具,grep和sed都是不错的文本分析工具,还有awk,再过复杂的日志分析估计就要写脚本了,推荐使用Python。
(其实我一直在纳闷,数据分析这些事情,怎么老是需要服务器程序去查,有专门的数据中心、运维和客服部门,人家才是专业的,工具比咱用的更“专业”吧。最后想了想,公司流程不完善,游戏后台日志分析自己这边还是做起来,不然搞的太被动了也不好。)
下面是sed的一个快速参考,更加详细的介绍,还有用法实例,可以参考《sed and awk》那本书。或者本文后面的那几个链接,都有很好的介绍。
命令行语法
有两种调用sed的方式:
sed [-n] [-e] 'command' file(s) sed [-n] -f scriptfile file(s)
第一种方式允许在命令行指定一个编辑命令,用单引号括起来。第二种形式允许指定一个scriptfile,即包含sed命令的文件。两种形式可以一起使用,并且他们可以被多次使用。编辑的结构是将命令和脚本文件串联起来。
下面是可识别的选项:
-n 仅打印用p命令或s命令标记指定的行 -e cmd 下一个参数是编辑命令。当指定多个脚本时很有用。 -f file 下一个参数是一个包含编辑命令的文件。
如果脚本的第一行是”#n”,sed将按-n指定的方式工作。
频繁使用sed脚本通常是通过shell脚本来调用的。
sed命令语法
sed命令的一般形式为:
[address[,address]][!]command[arguments]
sed将每个输入行拷贝到一个模式空间。sed指令由地址和编辑命令组成。如果命令的地址和模式空间中的行匹配,那么这个命令将被应用于匹配行。如果一个命令没有地址,那么它被应用于每个输入行。如果一个命令改变了模式空间的内容,后续的命令地址将被应用与模式空间中的当前行,而不是原始的输入行。
模式寻址
地址可以是一个行号或是由斜杠包含着的一个模式(/pattern/)。模式是用正则表达式表示的。另外,\n可以用来与模式空间(N命令的结果)的任意换行符匹配,但模式空间底部的换行符除外。
如果没有指定模式,相应的命令将被应用于所有的行。如果只指定一个地址,那么相应的命令将被应用于和这个地址匹配的行。如果指定了两个用逗号分隔的地址,这个命令将被应用于位于第一个和第二个地址范围之间的所有行。一些命令只接收一个地址,包括a,i,r,q和=。
在地址后面的”!”操作符使sed将相应的命令作用于所有与该地址不匹配的行。
大括号({})被sed用于地址的嵌套或对同一个地址应用多个命令。
[/pattern/[,/pattern/]] { command1 command2 }
左大括号必须在一行的末尾,而右括号必须单独在一行。确保大括号后面没有空格。
sed中的正则表达式元字符
. |
匹配除换行符以为的任意单个字符 |
* |
匹配任意个(包括0个)在它前面的字符(包括由正则表达式指定的字符) |
[...] |
匹配广括号中的字符中的任意一个字符。其它所有的元字符被指定为其中成员时都会失去它们原来的含义。如果方括号第一个字符为脱字符(^)则匹配除了换行符和列出的那些字符以为的所有字符。连字符(-)用来表示字符的范围。如果其中第一个字符为右方括号(]),则表示它是这个类的成员。 |
\{n,m\} |
它前面的某个范围内单个字符出现的次数(保护正则表达式指定的字符)。\{n\}将匹配n次出现,\{n,\}匹配大于等于n次出现的。 |
^ |
定位位于行起始位置后面的正则表达式。只有当^符号出现在正则表达式的起始位置时才是特殊的。 |
$ |
定位位于行末尾的正则表达式,只有当$符号出现在正则表达式的末尾时才是特殊的。 |
\ |
转义随后的特殊字符 |
\( \) |
将包含在”"和”"之间的模式保存到一个特殊的保持空间。用这种方法在一行中可以最多保存9个模式。用转义序列”\1″ 到 “\9″ 可以重新使用它们。 |
\n |
匹配前面”"和”"保存的第n个模式,这里n是一个从1到9的数字,前面保存的模式从行的左边开始编号。 |
& |
当在替换字符串中使用时打印整个被匹配的文本 |
sed命令参考
命令 | 说明 |
---|---|
: :lable |
在脚本中标记一行,用于实现由b或t的控制转移。label最多可以包含7个字符。(GNU sed允许标签的长度任意) |
= [address]= |
将所寻址的行编号写到标准输出。 |
a [address]a\ text |
在与address匹配的每行后面追加text。如果text多于一行,必须用反斜杠将这些行前面的换行符“隐藏”起来。text将被没有用这种方法隐藏的第一个换行符结束。text在模式空间中不是可用的并且后续命令不能应用于它。当编辑命令的列表用完时这个命令的结果将被输送到标准输出,而不管在模式空间中的当前行发生了什么。 |
c [address1[,address2]]c \ text |
用text代替(改变)由地址选定的行。当指定的是一个行范围时,将所有的这些行为作为一个组由text的一个副本来代替。每个text行后面的换行符必须用反斜杠将其转义,但最后一行除外。实际上,模式空间的内容被删除,因此后续的命令不能应用于它(或应用于text) |
d [address1[,address2]]d |
从模式空间中删除行。因此行没有被传递到标准输出。一个新的输入行被读取,并用脚本的第一个命令来编辑。 |
D [address1[,address2]]D |
删除由命令N穿件的多行模式空间中的第一部分(直接嵌入的换行符),并且用脚本的第一条命令恢复编辑。如果这个命令使模式空间为空,那么将读取一个新的输入行,和执行了d命令。 |
g [address1[,address2]]g |
将保持空间中的内容复制到模式空间。如果保持空间为空,则将换行符添加到模式空间。 |
G [address1[,address2]]G |
将保持空间中的内容追加到模式空间。如果保持空间为空,则将换行符添加到模式空间。 |
h [address1[,address2]]h |
将模式空间的内容复制到保持空间,即一个特殊的临时缓冲区。保持空间的当前内容被清楚。 |
H [address1[,address2]]H |
将换行符和模式空间的内容追加到保持空间中,即使保持空间为空,这个命令也追加换行符。 |
i [address]i\ text |
将text插入到每个和address匹配的行的前面。 |
l [address1[,address2]]l |
列出模式空间的内容,将不可打印的字符表示为ASCII码。长的行被折行。 |
n [address1[,address2]]n |
读取下一个输入行到模式空间。当前行被送到标准输出。新行成为当前行并递增计数器。将控制转到n后面的命令,而不是恢复到脚本的顶部。 |
N [address1[,address2]]N |
将下一个输入行追加到模式空的内容之后;新添加的行与模式空间的当前内容用换行符分隔(这个命令用于实现两行的模式匹配。利用\n来匹配嵌入的换行符,则可以实现多行模式匹配) |
p [address1[,address2]]p |
打印所寻址的行。注意这将导致输出的重复,除非默认的输出用”#n”或”-n”命令行选项限制。常用于改变流控制(d,n,b)的命令之前并可能阻止当前行被输出。 |
P [address1[,address2]]P |
打印由N命令创建的多行模式空间的地一部分(直接嵌入的换行符)。如果没有将N应用于某一行则和p相同。 |
q [address]q |
当遇到address时退出。寻址的行首先被写到输出(如果没有限制默认输出),包括用前面的a或r命令为它追加的文本。 |
r [address]r file |
读取file的内容并追加到模式空间内容的后面。必须在r和文件名file之间保留一个空格。 |
s [address1[,address2]]s/pattern/replacement/[flags] |
用replacement代替每个寻址行的pattern。如果使用了模式地址,那么模式//表示最后指定的模式地址。可指定下面的标志。
|
t [address1[,address2]]t [label] |
测试在寻址的行范围内是否成功执行了替换,如果是,则转移到有lable标志的行。如果没有给出lable,控制转移到脚本的底部。 |
w [address1[,address2]]w file |
将模式空间的内容追加到file。这个动作是在遇到命令时发生而不是在输出模式空间内容时发生。必须在w和这个文件名之间保留一个空格。在脚本中可以打开的最大文件数是10。如果文件不存在,这个命令将创建一个文件。如果文件存在,则每次执行脚步时将修改其内容,多重写入命令直接将输出写入到同一个文件并追加到这个文件的末端。 |
x [address1[,address2]]x |
交换模式空间和保持空间的内容。 |
y [address1[,address2]]y/abc/xyz/ |
安位置将字符串abc中的字符转换成字符串xyz中的相应该字符。 |
更多参考资料
2012/04/20 23:45 于上海