【Bash百宝箱】sed

来源:互联网 发布:简单数据流程图例题 编辑:程序博客网 时间:2024/04/29 16:54

sed是一个流编辑工具,从文件或管道中读取输入流,以行为单位,对字符串进行一定的处理后输出处理结果。

sed命令基本格式如下:

sed <OPTIONS> <input-files>sed -f script-file <input-files>

OPTIONS为sed命令的参数,不过这些参数可以放在一个文件script-file中,通过“-f script-file”指定即可,input-files为待处理的文件,可以是空格分隔的多个文件。先介绍几个有用的参数:

-n:禁止打印处理结果,不修改文件时(不使用“-i”)默认是会打印的。-e script:不使用“-e”时,只能执行一个命令,如果想执行多个命令,就要在每个命令(script)前使用“-e”,这样就可以一次性执行多个命令而不出错。-i[SUFFIX]:修改文件,若指定了SUFFIX,则对文件进行备份,备份文件名为文件名加后缀SUFFIX,默认是不修改文件的。--follow-symlinks:修改符号文件时,连同指向的原文件一起修改,默认是不修改原文件只修改符号文件的,这样也就破坏了符号链接关系。-l N:仅对命令“l”有效,指定每行打印的最多字符数,超过N时将使用续行符“\”进行换行。--posix:禁用GNU扩展,sed命令的某些功能如“l width”为GNU扩展,禁用后再使用时将出错。-r:扩展正则表达式,比如说花括号“{}”,否则要使用转义字符“\”进行转义。-s:处理多个文件时,分别对待它们,否则这些文件被当作一个输入流,也可以理解为一个大文件,有可能达不到预期效果。-u:输入、输出buffer尽可能小。-z:行分隔符替换为空字符,多行文本犹如一行长文本。

sed涉及两个概念,命令和地址,有些命令需要指定地址,有些则不需要。地址即行号,下面是地址的用法:

number          一个数字,指定行号,第一行为1。$                     最后一行。first~step        匹配第first行及之后的每隔step行数的行。addr1,+N        匹配addr1及紧随其后的N行。addr1,~N        匹配addr1及紧随其后的直到行号为N的行,包括第N行。first,last           匹配第first行与第last行之间的行,包括第first行和第last行。/regexp/          匹配与正则表达式regexp相符的行。\CregexpC       匹配与正则表达式regexp相符的行,C为标记字符,可以是任意字符。

下面以例子说明sed命令的详细用法。

字符替换

1、“y/source/dest/”把文本行中与source中的各字符相同的字符逐渐替换为dest中的各字符,这意味着source与dest的字符个数必须相等,且替换是一一对应的,即source中的第n个字符替换为dest中的第n个字符。

$ echo "abc123abc123" | sed y/a1/x0/xbc023xbc023

交换buffer与匹配行

2、“x”交换buffer与匹配的内容,如下例子中,buffer初始值为空,所以输出的第一行也为空,第二行为原文件的第一行,第三行为源文件的第二行。

$ cat script x$ cat file123$ sed -f script file12

结果保存到文件

3、“w filename”把结果输出到文件filename,如下例子中,把文件file中的“1”替换为“x”,结果打印到屏幕的同时还保存到了文件output。

$ cat script y/1/x/w output$ cat file 123$ sed -f script file x23$ cat output x23

正则替换字符串

4、“s/regexp/replacement/”把文本行中与正则表达式regexp匹配的内容替换为replacement,如下例子中,把“an”替换为“ONE”。

$ echo "this is an example" | sed s/an/ONE/this is ONE example

下面是一个高级用法,符号“&”表示匹配到的内容,因为是特殊字符,所以需要转义或者使用“-r”,使用“-r”时需要单引号或双引号,例子中给“an”前后各添加一个短横线。

$ echo "this is an example" | sed s/an/-\&-/this is -an- example$ echo "this is an example" | sed -r "s/an/-&-/"this is -an- example$ echo "this is an example" | sed -r 's/an/-&-/'this is -an- example

正则表达式可以使用圆括号进行分组,匹配到的内容用“\n”表示,n从1到9,表示圆括号的序号,如下例子中,正则表达式有4个分组,只显示与第3、4个分组匹配的内容。

$ echo "this is an example" | sed -r 's/(this) (is) (an) (example)/\3 \4/'an example

行首、行尾添加内容:

$ echo "hello sed" | sed 's/^/xxx/'xxxhello sed$ echo "hello sed" | sed 's/$/xxx/'hello sedxxx

打印匹配行

5、“p”打印匹配的内容,如下几个例子作了对比,默认打印匹配的内容和没有匹配的内容,“-n”禁止输出,同时使用“-n”和“p”则只打印匹配的内容。

$ cat file 123$ sed s/1/x/ file x23$ sed -n s/1/x/ file$ sed -n s/1/x/p file x$ sed s/1/x/p file xx23

处理下一行

6、“n”、“N”对于匹配的内容来说,前者读下一行,后者追加下一行,如下例子所示。

$ sed -e 's/1/x/' file x23x12233$ sed -e n -e 's/1/x/' file 123x12233$ sed -e N -e 's/1/x/' file x23x12233

特殊格式打印匹配行

7、“l”以一种特殊的格式显示各行,比如说添加行尾标记符。

$ cat file 123$ sed l file 1$12$23$3$ sed -n l file 1$2$3$

buffer与匹配行

8、“h”、“H”、“g”、“G”分别表示复制匹配内容到buffer、追加匹配内容到buffer、复制buffer到匹配内容、追加buffer到匹配内容,如下例子所示,使用了“G”,buffer为空,每个匹配行后多了1个空行。

$ cat file 123112233$ sed -n -e 's/1/x/p' file xx1$ sed -n -e G -e 's/1/x/p' file xx1

删除行

9、“d”删除命令,如下例子所示。

$ cat file 123112233$ sed 1d file 23112233$ sed 1,5d file 33

替换行

10、“cXXX”用XXX替换整行内容,如下例子中,替换第2行为“===”。

$ cat file 123112233$ sed 2c=== file 1===3112233

追加外部文本

11、“r filename”、“R filename”分别表示在每行后追加filename中的所有内容、在每行后追加filename中的一行(从filename中的第一行开始,依次读取第二行、第三行……),如下例子所示。

$ cat file 123$ cat ext123abc======$ sed -e 's/1/x/' file x23$ sed -e 'r ext' -e 's/1/x/' file x123abc======2123abc======3123abc======$ sed -e 'R ext' -e 's/1/x/' file x123abc2======3

插入行

12、“iXXX”行前插入内容为XXX的一行,如下例子所示,在第二行前插入“hellosed”。

$ cat file 123$ sed 2ihellosed file 1hellosed23

追加行

13、“aXXX”行后追加内容为XXX的一行,如下例子所示,在第二行后追加“hellosed”。

$ cat file 123$ sed 2ahellosed file 12hellosed3

打印行号

14、“=”打印行号,行号独立一行输出,如下例子所示。

$ cat file hellosed$ sed = file1hello2sed

标签

15、使用冒号标记一个标签,然后使用“b”跳转到某个标签,类似于C的goto,直接看如下例子。

$ cat file 123456123456123456$ cat script :num1 s/1/x/:num2 s/2/x/:num3 s/3/x/$ sed -f script filexxx456xxx456xxx456$ sed -e 'b' -f script file123456123456123456$ sed -e 'b num1' -f script filexxx456xxx456xxx456$ sed -e 'b num2' -f script file1xx4561xx4561xx456$ sed -e 'b num3' -f script file12x45612x45612x456$ sed -e 'b num4' -f script filesed: can't find label for jump to `num4'

最后补充一下,命令“q”、“Q”表示立即终止sed执行,符号“#”为注释符,类似于shell的“#”、C/C++的“//”,命令可以放在一对花括号中。

1 0
原创粉丝点击