sed
是一个非交互式文本编辑器(流式编辑器),它可对文本文件和标准输入进行编辑,标准输入可以是来自键盘输入、文件重定向、字符串、变量,甚至来自管道的文本。sed 从文本的一个文本行或标准输入中读取数据,将其存储到临时缓冲区,也称为“模式空间”(pattern space
),然后读取命令行或脚本的第一个命令,对此命令要求的行号进行编辑,重复此过程,直到命令行或脚本中的所有命令都执行完毕。相对如 vim 等其它文本编辑器,sed 可以一次性处理所有的编辑任务,显得非常高效,为用户节省了大量时间,sed
适用于以下三种场合。
- 编辑相对交互式文本编辑器而言太大的文件
- 编辑命令太复杂,在交互式文本编辑器中难以输入的情况
- 对文件扫描一遍,但是需要执行多个编辑函数的情况
sed
只是对缓冲区中原始文件的副本进行编辑,并不编辑原始的文件。
命令选项:
x
x 为指定行号
x,y
指定从 x 到 y 的行号范围
/pattern/
查询包含模式的行
/pattern/pattern/
查询包含两个模式的行
/pattern/,x
从与 pattern 的匹配行到 x 号行之间的行
x,/pattern/
从 x 号行与 pattern 的匹配行之间的行
x,y!
查询不包括 x 和 y 行号的行
p
打印匹配行
=
打印文件行号
a\
在定位行号之后追加文本信息
i\
在定位行号之前插入文本信息
d
删除定位行
c\
用新文本替换定位文本
s
使用替换模式替换相应模式
r
从另一个文件读文本
w
将文本写入到一个文件
y
变换字符
q
第一个模式匹配完成后退出
l
显示与八进制 ASCII 码等价的控制字符
{}
在定位行执行的命令组
n
读取下一个输入行,用下一个命令处理新的行
h
将模式缓冲区的文本复制到保持缓冲区
H
将模式缓冲区的文本追加到保持缓冲区
x
互换模式缓冲区和保持缓冲区内容
g
将保持缓冲区的内容复制到模式缓冲区
G
将保持缓冲区的内容追缴到模式缓冲区
应用实例:
1. 在每行行首增加一个#
sed 's/^/#/g'
2. 替换第一个字符为#
sed 's/^./#/g'
sed 's/^../#/g' //替换前2个
3. 替换最后一个 root 为 hello
sed 's/\(.*\)root/\1hello/'
4. 替换倒数第2个root为hello
sed 's/\(.*\)root\(.*root\)/\1hello\2/'
3.替换每行第二个到第六个字符为*
sed '{s/./*/2;s/./*/3;s/./*/4;s/./*/5;s/./*/6;}'
4.替换1到10行第二个到第六个字符为*
sed '1,10{s/./*/2;s/./*/3;s/./*/4;s/./*/5;s/./*/6;}'
5. 每行行尾添加字符串 aaa
sed 's/$/aaa/g'
6. 1到5行行尾添加字符串 aaa
sed '1,5s/$/aaa/g'
6. 删除所有的 aaa
sed 's/aaa//g'
7. 删除1到5行的 aaa
sed '1,5s/aaa//g'
8. 删除每行第一个匹配的aaa
sed 's/aaa//1'
7. 删除包含 aaa 的行
sed '/aaa/d'
8. 删除包含 aaa 的1到5行
sed '1,5/aaa/d'
9. 删除指定行,第一行
sed '1d'
10. 删除1到5行
sed '1,5'
11. 删除空白行
sed '/^$/d'
12. 打印空白行
sed -n '/^$/p'
13. 从第3行开始,每隔1行删除
sed '3~2d'
14. 从第3行开始,每隔2行删除
sed '3~3d'
15. 从第3行开始,每一行都删除
sed '3~1d'
7. 在每一行后面增加一空行
sed G
8. 在每一行后面增加两空行
sed 'G;G'
从第1行开始,每隔2行增加一空行
sed '1~2G'
7. 将原来的所有空行删除并在每一行后面增加一空行。这样在输出的文本中每一行后面将有且只有一空行。
sed '/^$/d;G'
8. 在每一行后面增加两行空行
sed 'G;G'
9. 删除偶数行
sed 'n;d'
10. 在匹配“hello”的行之前插入一空行
sed '/hello/{x;p;x;}'
11. 在匹配“hello”的行之后插入一空行
sed '/hello/G'
12. 在匹配式样“hello”的行之前和之后各插入一空行
sed '/hello/{x;p;x;G;}'
13. 为文件中的每一行进行编号(简单的左对齐方式)。 这里使用了“制表符”
sed = filename | sed 'N;s/\n/\t/'
15. 对文件中的所有行编号,但只显示非空白行的行号。
sed '/./=' filename | sed '/./N; s/\n/ /'
16. 计算行数 (模拟 "wc -l")
sed -n '$='
17. 将每一行前开头的“空白字符”(空格,制表符)删除使之左对齐
sed 's/^[ \t]*//'
18. 将每一行结尾的“空白字符”(空格,制表符)删除
sed 's/[ \t]*$//
19. 将每一行中的开头和结尾的空白字符删除
sed 's/^[ \t]*//;s/[ \t]*$//'
20. 在每一行开头处插入5个空格(使全文向右移动5个字符的位置)
sed 's/^/ /'
21. 在每一行中查找字串“foo”,并将找到的“foo”替换为“bar”
sed 's/foo/bar/' # 只替换每一行中的第一个“foo”字串 sed 's/foo/bar/4' # 只替换每一行中的第四个“foo”字串 sed 's/foo/bar/g' # 将每一行中的所有“foo”都换成“bar” sed 's/\(.*\)foo\(.*foo\)/\1bar\2/' # 替换倒数第二个“foo” sed 's/\(.*\)foo/\1bar/' # 替换最后一个“foo”
22. 只在行中出现字串“baz”的情况下将“foo”替换成“bar”
sed '/baz/s/foo/bar/g'
23. 将“foo”替换成“bar”,并且只在行中未出现字串“baz”的情况下替换
sed '/baz/!s/foo/bar/g'
24. 不管是“scarlet”“ruby”还是“puce”,一律换成“red”
sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g'
25. 倒置所有行,第一行成为最后一行,依次类推(模拟“tac”)
sed '1!G;h;$!d' # 方法1 sed -n '1!G;h;$p' # 方法2
26. 将行中的字符逆序排列,第一个字成为最后一字,……(模拟“rev”)
sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
27. 将每两行连接成一行(类似“paste”)
sed '$!N;s/\n/ /'
28. 如果当前行以反斜杠“\”结束,则将下一行并到当前行末尾并去掉原来行尾的反斜杠
sed -e :a -e '/\\$/N; s/\\\n//; ta'
29. 如果当前行以等号开头,将当前行并到上一行末尾并以单个空格代替原来行头的“=”
sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'
30. 为数字字串增加逗号分隔符号,将“1234567”改为“1,234,567”
sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta'
为带有小数点和负号的数值增加逗号分隔符
sed -r ':a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta'
31. 在每5行后增加一空白行 (在第5,10,15,20,等行后增加一空白行)
gsed '0~5G' sed 'n;n;n;n;G;'
32. 显示文件中的前10行 (模拟“head”的行为)
sed 10q
33. 显示文件中的第一行 (模拟“head -1”命令)
sed q
34. 显示文件中的最后10行 (模拟“tail”)
sed -e :a -e '$q;N;11,$D;ba'
35. 显示文件中的最后2行(模拟“tail -2”命令)
sed '$!N;$!D'
36. 显示文件中的最后一行(模拟“tail -1”)
sed '$!d' sed -n '$p'
37. 显示文件中的倒数第二行
sed -e '$!{h;d;}' -e x # 当文件中只有一行时,输入空行 sed -e '1{$q;}' -e '$!{h;d;}' -e x # 当文件中只有一行时,显示该行 sed -e '1{$d;}' -e '$!{h;d;}' -e x # 当文件中只有一行时,不输出
38. 只显示匹配正则表达式的行(模拟“grep”)
sed -n '/regexp/p' # 方法1 sed '/regexp/!d' # 方法2
39. 只显示“不”匹配正则表达式的行(模拟“grep -v”)
sed -n '/regexp/!p' # 方法1,与前面的命令相对应 sed '/regexp/d' # 方法2,类似的语法
40. 查找“regexp”并将匹配行的上一行显示出来,但并不显示匹配行
sed -n '/regexp/{g;1!p;};h'
41. 查找“regexp”并将匹配行的下一行显示出来,但并不显示匹配行
sed -n '/regexp/{n;p;}'
42. 显示包含“regexp”的行及其前后行,并在第一行之前加上“regexp”所在行的行号 (类似“grep -A1 -B1”)
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h
43. 显示包含“AAA”、“BBB”或“CCC”的行(任意次序)
sed '/AAA/!d; /BBB/!d; /CCC/!d' # 字串的次序不影响结果
44. 显示包含“AAA”、“BBB”和“CCC”的行(固定次序)
sed '/AAA.*BBB.*CCC/!d'
45. 显示包含“AAA”“BBB”或“CCC”的行 (模拟“egrep”)
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
46. 显示包含“AAA”的段落 (段落间以空行分隔)HHsed v1.5 必须在“x;”后加入“G;”,接下来的3个脚本都是这样
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'
47. 显示包含“AAA”“BBB”和“CCC”三个字串的段落 (任意次序)
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'
48. 显示包含“AAA”、“BBB”、“CCC”三者中任一字串的段落 (任意次序)
sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
49. 显示包含65个或以上字符的行
sed -n '/^.\{65\}/p'
50. 显示包含65个以下字符的行
sed -n '/^.\{65\}/!p' sed '/^.\{65\}/d'
51. 显示部分文本——从包含正则表达式的行开始到最后一行结束
sed -n '/regexp/,$p'
52. 显示部分文本——指定行号范围(从第8至第12行,含8和12行)
sed -n '8,12p' sed '8,12!d'
53. 显示第52行
sed -n '52p' sed '52!d' sed '52q;d'
54. 从第3行开始,每7行显示一次
gsed -n '3~7p' sed -n '3,${p;n;n;n;n;n;n;}'
55. 显示两个正则表达式之间的文本(包含)
sed -n '/Iowa/,/Montana/p' # 区分大小写方式
56. 显示通篇文档,除了两个正则表达式之间的内容
sed '/Iowa/,/Montana/d'
57. 删除文件中相邻的重复行(模拟“uniq”)只保留重复行中的第一行,其他行删除
sed '$!N; /^\(.*\)\n\1$/!P; D'
58. 删除文件中的重复行,不管有无相邻。注意hold space所能支持的缓存大小,或者使用GNU sed。
sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'
59. 删除除重复行外的所有行(模拟“uniq -d”)
sed '$!N; s/^\(.*\)\n\1$/\1/; t; D'
60. 删除文件中开头的10行
sed '1,10d'
61. 删除文件中的最后一行
sed '$d'
62. 删除文件中的最后两行
sed 'N;$!P;$!D;$d'
63. 删除文件中的最后10行
sed -e :a -e '$d;N;2,10ba' -e 'P;D' # 方法1 sed -n -e :a -e '1,10!{P;N;D;};N;ba' # 方法2
64. 删除8的倍数行
sed '0~8d' sed 'n;n;n;n;n;n;n;d;'
65. 删除匹配式样的行
sed '/pattern/d' # 删除含pattern的行。当然pattern可以换成任何有效的正则表达式
66. 删除文件中的所有空行(与“grep '.' ”效果相同)
sed '/^$/d' # 方法1 sed '/./!d' # 方法2
67. 只保留多个相邻空行的第一行。并且删除文件顶部和尾部的空行。(模拟“cat -s”)
sed '/./,/^$/!d' #方法1,删除文件顶部的空行,允许尾部保留一空行 sed '/^$/N;/\n$/D' #方法2,允许顶部保留一空行,尾部不留空行
68. 只保留多个相邻空行的前两行。
sed '/^$/N;/\n$/N;//D'
69. 删除文件顶部的所有空行
sed '/./,$!d'
70. 删除文件尾部的所有空行
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' # 对所有sed有效 sed -e :a -e '/^\n*$/N;/\n$/ba' # 同上,但只对 gsed 3.02.*有效
71. 删除每个段落的最后一行
sed -n '/^$/{p;h;};/./{x;/./p;}'