sed:Stream Editor文本,sed是一个非交互式的面向字符流的编辑器。能同时处理多个文件多行的内容。
sed编辑器是一行一行的处理文件,正在处理的内容存放在模式空间(缓冲区)中,处理完毕后按照选项的规定进行输出或文件的修改。
sed主要用来自动编辑一个或多个文件;简化文件的反复操作,用于非交互编译文件。
1. 语法
sed [options] '[command]' [filename]
1. sed命令的选项(option)
选项 | 作用 |
---|---|
-n | 只打印模式匹配的行 |
-e | 直接在命令行模式上进行sed动作编辑,此为默认选项 |
-f | 将sed的动作写在一个文件内 |
-r | 支持扩展表达式 |
-i | 直接修改文件内容 |
2. sed命令的命令(command)
命令 | 作用 |
---|---|
p | 打印匹配行(和-n选项一起使用) |
= | 显示文件行的行号 |
a | 在定位行号后附加新文本信息 |
i | 在定位行号后插入新文件信息 |
d | 删除定位行 |
c | 用新文本替换文本 |
w filename | 写文本到一个文件,类似输出重定向 |
r filename | 从另一个文件中读文件,类似输出重定向 |
s | 使用替换模式替换相应模式 |
q | 第一个模式匹配完成后退出或立即退出 |
I | 显示与八进制ACSII代码等价的控制符 |
{} | 在定位行执行的命令组,用;隔开 |
g | 将模式2粘贴到/pattern n/ |
2. 实战
2.1 sed在文件中查询文本方式
1. 使用行号打印特定行
可以使用一个简单的数字,或是一个行号范围
注意:p的动作是:打印匹配行。
格式 | 说明 |
---|---|
xp | x为行号 |
x,yp | 表示行号从x到y |
/pattern/p | 查询包含模式的行 |
/pattern /pattern/p | 查询包含两个模式的行 |
/pattern/,xp | 包含模式和指定行号之间的行 |
x,/pattern/p | 通过行号和模式查询匹配的行 |
x,y! | 查询不包含指定行号x和y的行 |
1. 原始文件:
[newsettle@localhost userbin]$ cat exam.log
#/bin/sh
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
2. sed的默认动作
(1)sed的默认动作是打印文件中的所有行。
[newsettle@localhost userbin]$ sed '' exam.log
#/bin/sh
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
3. 打印特定行
(1)因为sed命令默认打印文件中所有行。所以第三行会被打印两遍。那如何只打印第三行呢?使用【-n】命令,只打印匹配的行。
[newsettle@localhost userbin]$ sed '3p' exam.log
#/bin/sh
第三行111
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
(2)使用【-n】命令,只打印匹配到的行
[newsettle@localhost userbin]$ sed -n '3p' exam.log
第三行111
(3)打印[n,m]行
[newsettle@localhost userbin]$ sed -n '3,4p' exam.log
第三行111
第四行222
(4)打印包含模式的行
[newsettle@localhost userbin]$ sed -n '/八/p' exam.log
END 第八行END
(5)打印包含模式和指定行号之间的行
[newsettle@localhost userbin]$ sed -n '/四/,6p' exam.log
第四行222
第五行333
第六行444
[newsettle@localhost userbin]$ sed -n '1,/四/p' exam.log
#/bin/sh
第三行111
第四行222
(6)包含模式和包含模式之间的行
[newsettle@localhost userbin]$ sed -n '/三/,/四/p' exam.log
第三行111
第四行222
(7){}执行多个命令(command),使用;隔开。=是显示文件行的行号。p是打印匹配行
[newsettle@localhost userbin]$ sed -n '1,4{=;p}' exam.log
1
#/bin/sh
2
3
第三行111
4
第四行222
(8)!取反操作
[newsettle@localhost userbin]$ sed -n '1,4!{=;p}' exam.log
5
第五行333
6
第六行444
7
第七行555
8
END 第八行END
9
END 第就行END
10
第十行 3.1
11
第十一行 YES--我是真的YES 不你不YES
(9)q命令:第一个模式匹配完成后退出或立即退出,使用该命令打印前5行
[newsettle@localhost userbin]$ sed '5q' exam.log
#/bin/sh
第三行111
第四行222
第五行333
2. 使用正则表达式匹配行
模式 | 说明 |
---|---|
^ | 锚点行首的符合条件的内容,用法格式"^pattern" |
$ | 锚点行尾的符合条件的内容,用法格式"pattern$" |
^$ | 空白行 |
. | 匹配单个字符 |
* | 匹配紧挨着前面字符的0次或多次 |
.* | 匹配任意长度的任意字符 |
? | 匹配紧挨在前面字符0次或1次 |
{m,n} | 匹配紧挨前面字符至少m次,至多n次 |
{m,} | 匹配紧挨前面字符至少m次 |
<pattern> | 匹配特定单词 |
[] | 匹配指定范围内的任意单个字符 |
[^] | 匹配指定范围外的任意单个字符 |
[:digit:] | 所有数字;相当于0-9,[0-9]-->[[:digit:]] |
[:lower:] | 所有的小写字母 |
[:upper:] | 所有的大写字母 |
[:alpha:] | 所有的字母 |
[:alnum:] | 相当于0-9a-zA-Z |
[:space:] | 空白字符 |
[:punct:] | 所有标点符号 |
(1)使用[]进行正则匹配
[newsettle@localhost userbin]$ sed -n '/[[:digit:]]/p' exam.log
第三行111
第四行222
第五行333
第六行444
第七行555
第十行 3.1
[newsettle@localhost userbin]$ sed -n '/[1-3]/p' exam.log
第三行111
第四行222
第五行333
第十行 3.1
(2)其他的正则表达式
sed-n '/r*t/p'/etc/passwd#打印匹配r有0个或者多个,后接一个t字符的行
sed-n '/.r.*/p'/etc/passwd#打印匹配有r的行并且r后面跟任意字符
sed-n '/o*/p'/etc/passwd#打印o字符重复任意次
sed-n '/o\{1,\}/p'/etc/passwd#打印o字重复出现一次以上
sed-n '/o\{1,3\}/p'/etc/passwd#打印o字重复出现一次到三次之间以上
2.2 对文件的操作
对文件的操作无非就是“增改删查”,sed命令怎样实现对文件的操作呢?
1. 文件的查询
(1)打印出以#开头的行,然后用!进行反选,则表示过滤掉以#开头的行,不会过滤掉空格。
[newsettle@localhost userbin]$ sed -n '/^#/!p' exam.log
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
(2)匹配以#开头的行,进行取反,则打印出非#开头的行,然后其结果在对空格开头的行进行取反。即过滤掉以#开头的行和以空格开头的行。{}表示在定位行执行的命令组。
[newsettle@localhost userbin]$ sed -n '/^#/!{/^$/!p}' exam.log
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
(3)sed支持对单个文件实现不同的操作,每个操作用-e参数。定位到执行的行后,使用d命令,直接删除匹配到的行。
[newsettle@localhost userbin]$ sed -e '/^#/d' -e '/^$/d' exam.log
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
2. 文件的添加
需要注意的是,对源文件的添加要使用【-i】参数。
s:使用替换模式替换相应模式
(1)在匹配行前面替换字符,使用【s】命令。
[newsettle@localhost userbin]$ sed '/六/s/^/我是 /' exam.log
#/bin/sh
第三行111
第四行222
第五行333
我是 第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
(2)在所有行开头替换元素【s】
[newsettle@localhost userbin]$ sed 's/^/Start /' exam.log
Start #/bin/sh
Start
Start 第三行111
Start 第四行222
Start 第五行333
Start 第六行444
Start 第七行555
Start END 第八行END
Start END 第就行END
Start 第十行 3.1
Start 第十一行 YES--我是真的YES 不你不YES
(3)在所有行的末尾替换元素
[newsettle@localhost userbin]$ sed 's/$/ END/' exam.log
#/bin/sh END
END
第三行111 END
第四行222 END
第五行333 END
第六行444 END
第七行555 END
END 第八行END END
END 第就行END END
第十行 3.1 END
第十一行 YES--我是真的YES 不你不YES END
(4)指定行,进行替换操作
[newsettle@localhost userbin]$ sed '3,4s/^/#/' exam.log
#/bin/sh
#第三行111
#第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
(5)【&】符号代表的是匹配到的字符。在匹配到字符后,可以使用&代替。
[newsettle@localhost userbin]$ sed 's/第三行/你猜 &/' exam.log
#/bin/sh
你猜 第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
[newsettle@localhost userbin]$ sed 's/第三行/& 你猜 /' exam.log
#/bin/sh
第三行 你猜 111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
(6)在匹配到行前面添加一行,使用【i】的命令
[newsettle@localhost userbin]$ sed '/第四行/i 你好' exam.log
#/bin/sh
第三行111
你好
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
[newsettle@localhost userbin]$ sed '/第四行/i \你好' exam.log
#/bin/sh
第三行111
你好
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
(7)在匹配行的后面添加一行,使用【a】命令
[newsettle@localhost userbin]$ sed '/第四行/a 你好' exam.log
#/bin/sh
第三行111
第四行222
你好
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
(8)当添加多行时,使用\n来转义
[newsettle@localhost userbin]$ sed '/第四行/a 你好\n世界' exam.log
#/bin/sh
第三行111
第四行222
你好
世界
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
(9)@代表的是【地址定界符】,一般由三个组成,定界符可以是/,$,#等特殊字符,此命令表示,匹配特定字符的行进行替换。
[newsettle@localhost userbin]$ sed '/第三行/s@111@222@' exam.log
#/bin/sh
第三行222
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
需要注意的是:替换默认是修改匹配行中第一次出现的字符。
[newsettle@localhost userbin]$ sed '/YES/s@YES@NO@' exam.log
#/bin/sh
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 NO--我是真的YES 不你不YES
(10)使用命令【g】修改全文中出现的匹配字符。
[newsettle@localhost userbin]$ sed '/YES/s@YES@NO@g' exam.log
#/bin/sh
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 NO--我是真的NO 不你不NO
(11)若后面接数字之后在接g,表示匹配的行中,第几次出现。就替换,2g表示替换行中第二次出现。
[newsettle@localhost userbin]$ sed '/YES/s@YES@NO@2g' exam.log
#/bin/sh
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的NO 不你不NO
3. 文件行的删除
(1)删除以非#号开头的行,即显示以#号开头的行。
[newsettle@localhost userbin]$ sed '/^#/!d' exam.log
#/bin/sh
(2)删除第一行
[newsettle@localhost userbin]$ sed '1d' exam.log
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
(3)删除最后一行
[newsettle@localhost userbin]$ sed '$d' exam.log
#/bin/sh
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
(4)删除指定的行区间
[newsettle@localhost userbin]$ sed '3,5d' exam.log
#/bin/sh
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
(5)删除包含特定单词的行
[newsettle@localhost userbin]$ sed '/\<END\>/d' exam.log
#/bin/sh
第三行111
第四行222
第五行333
第六行444
第七行555
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
本文参考:
sed命令详解