【003】Linux Shell学习笔记-Sed用法详解
1 Sed 简介
1.1 Sed
sed是Linux下一款功能强大的非交互流式文本编辑器,可以对文本文件进行增、删、改、查等操作,支持按行、按字段、按正则匹配文本内容,灵活方便,特别适合于大文件的编辑。
1.2 工作原理
- 逐行处理
- 当从文件中读取一行后,首先放到模式空间中对该行进行相应的处理,处理完将结果输出到屏幕上。然后继续读取下一行内容,直到所有行都读取完毕,sed结束。
1.2 基本用法
语法
sed [选项] '定位 动作' 文件..
常用选项
-n:静默输出,关闭模式空间的输出,不会输出未匹配到的行 一般与p命令结合使用
-e:允许进行多项编辑,也就是说对同一行做多次处理、. 可以做多点编辑
-e '动作1' -e '动作2' == '动作1;动作2'
-f: 后接sed脚本,指定执行的sed脚本(将模式动作写到文件中)
-r:允许使用扩展正则
-i:直接作用于原文件 没有输出 在使用-i之前一定先不加-i看看效果
-i.bak:修改原文件之前进行备份
常用命令
a:追加 向匹配行后面插入内容
c:更改 更改匹配行的内容
i:插入 向匹配行前插入内容
d:删除 删除匹配的内容
s:替换 替换掉匹配的内容
p:打印 打印出匹配的内容,通常与-n选项和用
=:用来打印被匹配的行的行号
n:读取下一行,遇到n时会自动跳入下一行
r,w:读和写编辑命令,r用于将内容读入文件,w用于将匹配内容写入到文件
2 Sed 实例
2.1 添加或插入行
- 向第三行后面添加hello,3表示行号
[root@localhost ~]# cat a.txt
abc
123 123
def
456
123
[root@localhost ~]# sed '3ahello' a.txt #a:追加 向匹配行后面插入内容
abc
123 123
def
hello
456
123
- 向123后面添加hello (如果一行有多个123)则每一行后面都会添加
[root@localhost ~]# cat a.txt
abc
123 123
def
hello
456
123
[root@localhost ~]# sed '/123/ahello' a.txt
abc
123 123
hello
def
456
123
hello
- 在第三行前插入hello
[root@localhost ~]# cat a.txt
abc
123 123
def
456
123
[root@localhost ~]# sed '3ihello' a.txt
abc
123 123
hello
def
456
123
2.2 更改指定的行
- 将文件1.txt的第一行替换为hello
[root@localhost ~]# cat a.txt
abc
123 123
def
456
123
[root@localhost ~]# sed '1chello' a.txt
hello
123 123
def
456
123
- sed ‘/123/chello’ a.txt #将包含123的行替换为hello
- sed ‘$chello’ a.txt #将最后一行替换为hello
2.3 删除行
1. sed '4d' a.txt #删除第四行
2. sed '1~2d' a.txt #从第一行开始删除,每隔2行就删掉一行,即删除奇数行
3. sed '1,2d' a.txt #删除1~2行
4. sed '1,2!d' a.txt #删除1~2之外的所有行
5. sed '$d' a.txt #删除最后一行
6. sed '/123/d' a.txt #删除匹配123的行
7. sed '/123/,+1d' a.txt #删除匹配123的行及其后面一行
8. sed '/^$/d' a.txt #删除空行
9. sed '/123\|abc/!d' a.txt #删除不匹配123或abc的行,/123\|abc/ 表示匹配123或abc ,!表示取反
10. sed '1,3{/123/d}' a.txt #删除1-3行中,匹配内容123的行,1,3表示匹配1~3行,{/123/d}表示删除匹配123的行
2.4 替换内容
1. sed 's/^/#&/g' 1.txt #在a.txt文件中的每一行开头加一个#
2. sed 's/123/hello/' a.txt #将文件中的123替换为hello,默认只替换每行第一个123
3. sed 's/123/hello/g' a.txt #将文本中所有的123都替换为hello
4. sed 's/123/hello/2' a.txt #将每行中第二个匹配的123替换为hello
5. sed -n 's/123/hello/gpw 2.txt' a.txt #将每行中所有匹配的123替换为hello,并将替换后的内容写入2.txt
6. sed '/#/s/,.*//g' 1.txt #匹配有#号的行,替换匹配行中逗号后的所有内容为空 (,.*)表示逗号后的所又内容
7. sed 's/..$//g' 1.txt #替换每行中的最后两个字符为空,每个点代表一个字符,$表示匹配末尾 (..$)表示匹配最后两个字符
8. sed 's/^#.*//' 1.txt #将1.txt文件中以#开头的行替换为空行,即注释的行 ( ^#)表示匹配以#开头,(.*)代表所有内容
9. sed 's/^#.*//;/^$/d' 1.txt #先替换1.txt文件中所有注释的空行为空行,然后删除空行,替换和删除操作中间用分号隔开
10. sed 's/^[0-9]/(&)/' 1.txt #将每一行中行首的数字加上一个小括号 (^[0-9])表示行首是数字,&符号代表匹配的内容;
或者 sed 's/[0−9][0−9]/(\1)/' 1.txt #替换左侧特殊字符需钥转义,右侧不需要转义,\1代表匹配的内容
2.5 打印行
1. sed -n '3p' 1.txt #打印文件中的第三行内容
2. sed -n '2~2p' 1.txt #从第二行开始,每隔两行打印一行,波浪号后面的2表示步长
3. sed -n '$p' 1.txt #打印文件的最后一行
4. sed -n '1,3p' 1.txt #打印1到3行
5. sed -n '3,$p' 1.txt #打印从第3行到最后一行的内容
6. sed -n '/you/p' 1.txt #逐行读取文件,打印匹配you的行
7. sed -n '/bob/,3p' 1.txt #逐行读取文件,打印从匹配bob的行到第3行的内容
8. sed -n '/you/,3p' 1.txt #打印匹配you 的行到第3行,也打印后面所有匹配you 的行
9. sed -n '1,/too/p' 1.txt #打印第一行到匹配too的行
sed -n '3,/you/p' 1.txt #只打印第三行到匹配you的行
10. sed -n '/too/,$p' 1.txt #打印从匹配too的行到最后一行的内容
11. sed -n '/too/,+1p' 1.txt #打印匹配too的行及其向后一行,如果有多行匹配too,则匹配的每一行都会向后多打印一行
12. sed -n '/bob/,/too/p' 1.txt #打印从匹配内容bob到匹配内容too的行
2.6 打印行号
1. sed -n "$=" 1.txt #打印1.txt文件最后一行的行号(即文件有多少行,和wc -l 功能类似)
2. sed -n '/error/=' 1.txt #打印匹配error的行的行号; sed -n '/error/{=;p}' 1.txt #打印匹配error的行的行号和内容(可用于查看日志中有error的行及其内容)
2.7 读取内容
1. sed 'r 2.txt' 1.txt #将文件2.txt中的内容,读入1.txt中,会在1.txt中的每一行后都读入2.txt的内容
2. sed '3r 2.txt' 1.txt #在1.txt的第3行之后插入文件2.txt的内容(可用于向文件中插入内容)
3. sed '/245/r 2.txt' 1.txt #在匹配245的行之后插入文件2.txt的内容,如果1.txt中有多行匹配456则在每一行之后都会插入
4. sed '$r 2.txt' 1.txt #在1.txt的最后一行插入2.txt的内容
2.8 写入内容
1. sed -n 'w 2.txt' 1.txt #将1.txt文件的内容写入2.txt文件,如果2.txt文件不存在则创建,如果2.txt存在则覆盖之前的内容
2. sed -n '2w 2.txt' 1.txt #将文件1.txt中的第2行内容写入到文件2.txt
3. sed -n -e '1w 2.txt' -e '$w 2.txt' 1.txt #将1.txt的第1行和最后一行内容写入2.txt ; sed -n -e '1w 2.txt' -e '$w 3.txt' 1.txt #将1.txt的第1行和最后一行分别写入2.txt和3.txt
4. sed -n '/abc\|123/w 2.txt' 1.txt #将1.txt中匹配abc或123的行的内容,写入到2.txt中
5. sed -n '/666/,$w 2.txt' 1.txt #将1.txt中从匹配666的行到最后一行的内容,写入到2.txt中
6. sed -n '/xyz/,+2w 2.txt' 1.txt #将1.txt中从匹配xyz的行及其后2行的内容,写入到2.txt中
3 Sed 练习题
1.交换奇数行的第一个字符和倒数第二个单词(纯字母)
sed -r '1~1{s/(.)(.*)(\<[a-zA-Z]+)([^a-zA-Z]+)([a-zA-Z]+)/\3\2\1\4\5/' /tmp/pass
2.删除第2行到第5行中所有的数字
sed '2,5{s/[0-9]//g}' /tmp/pass
3.删除每行开头的所有空格
sed -r 's/^ //g' /tmp/pass
4.用制表符替换文件中出现的所有空白(多个连续的空白换成一个制表符\t)
sed -r 's/[[:space:]]+/\t/g' /tmp/pass
5.只打印2,5,8…这样的行
sed -n '2~3p' /tmp/pass
6.只打印包含有adm的行的第一个单词(纯字母)和第三个单词(纯字母),用#分隔
sed -rne 's/(\<[a-zA-Z]+)([^a-zA-Z]+)([a-zA-Z]+)([^a-zA-Z]+)([a-zA-Z]+)(.*)/\1#\5/;/adm/p' passwd
7.将所有行行尾的.替换成!
sed 's/.$/!/g' /tmp/pass
8.在第3行,第8行的倒数第一个字符和倒数第二个字符中插入@
sed -rn -e '3s/(.$)/@&/gp;8s/(.$)/@&/gp' /tmp/pass
9.只打印apahce主配置文件的有效行
sed -r -e '/^$/d;/[#]+/d' /etc/httpd/conf/httpd.conf
正则表达式
正则表达式sed练习
练习: head /etc/passwd > /tmp/pass
- 删除每行的第一个字符
sed 's/^.//g' /tmp/passwd
- 行首插入hello
sed '/^/hello/g' /tmp/passwd
- 删除每行的第二个字符
sed -r ‘s/(.)./\1/’ /tmp/psswd #把前两个字符保留第一个字符
- 把每个数字用()括起来 如:(1)(2)
sed -r 's/[0-9]/(&)/g' /tmp/passwd
- 把每个数值用()括起来 如:(12)
sed -r 's/[0-9]+/(&)/g' /tmp/passwd
- 删除每行的倒数第二个字符
sed -r 's/.(.)$/\1/g' /tmp/passwd
- 交换每行的第一个和最后一个字符
sed -r 's/^(.)(.*)(.)$/\2\1/g' /tmp/passwd
- 删除刚好三个字符的单词
sed -r 's/\<[a-zA-Z]{3}\>//g' /tmp/passwd
- 把ro或da替换成A
sed -r 's/ro|da/A/g' /tmp/passwd
- 删除每行的最后一个字母
sed -r 's/[a-zA-Z]([^a-zA-Z]*)$/\1/' /tmp/passwd
- 删除每行第一个单词
sed -r 's/[a-zA-Z]+//' /tmp/passwd
- 交换第一个和倒数第二个单词(纯字母)
sed -r 's/([a-zA-Z]+)(.*)(\<[a-zA-Z]+)([^a-zA-Z]+)([a-zA-Z]+)/\3\2\1\4\5/' /tmp/passwd
Reference
1.菜鸟教程
2. shell脚本–sed的用法 bywdz306ling
3. 课堂笔记