【Bash百宝箱】sed

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 file
1
2
3
$ sed -f script file

1
2

结果保存到文件

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

$ cat script 
y/1/x/
w output
$ cat file 
1
2
3
$ sed -f script file 
x
2
3
$ cat output 
x
2
3

正则替换字符串

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 
1
2
3
$ sed s/1/x/ file 
x
2
3
$ sed -n s/1/x/ file
$ sed -n s/1/x/p file 
x
$ sed s/1/x/p file 
x
x
2
3

处理下一行

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

$ sed -e 's/1/x/' file 
x
2
3
x1
22
33
$ sed -e n -e 's/1/x/' file 
1
2
3
x1
22
33
$ sed -e N -e 's/1/x/' file 
x
2
3
x1
22
33

特殊格式打印匹配行

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

$ cat file 
1
2
3
$ sed l file 
1$
1
2$
2
3$
3
$ sed -n l file 
1$
2$
3$

buffer与匹配行

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

$ cat file 
1
2
3
11
22
33
$ sed -n -e 's/1/x/p' file 
x
x1
$ sed -n -e G -e 's/1/x/p' file 
x

x1

删除行

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

$ cat file 
1
2
3
11
22
33
$ sed 1d file 
2
3
11
22
33
$ sed 1,5d file 
33

替换行

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

$ cat file 
1
2
3
11
22
33
$ sed 2c=== file 
1
===
3
11
22
33

追加外部文本

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

$ cat file 
1
2
3
$ cat ext
123abc
======
$ sed -e 's/1/x/' file 
x
2
3
$ sed -e 'r ext' -e 's/1/x/' file 
x
123abc
======
2
123abc
======
3
123abc
======
$ sed -e 'R ext' -e 's/1/x/' file 
x
123abc
2
======
3

插入行

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

$ cat file 
1
2
3
$ sed 2ihellosed file 
1
hellosed
2
3

追加行

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

$ cat file 
1
2
3
$ sed 2ahellosed file 
1
2
hellosed
3

打印行号

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

$ cat file 
hello
sed
$ sed = file
1
hello
2
sed

标签

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

$ cat file 
123456
123456
123456
$ cat script 
:num1 s/1/x/
:num2 s/2/x/
:num3 s/3/x/
$ sed -f script file
xxx456
xxx456
xxx456
$ sed -e 'b' -f script file
123456
123456
123456
$ sed -e 'b num1' -f script file
xxx456
xxx456
xxx456
$ sed -e 'b num2' -f script file
1xx456
1xx456
1xx456
$ sed -e 'b num3' -f script file
12x456
12x456
12x456
$ sed -e 'b num4' -f script file
sed: can't find label for jump to `num4'

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值